提取主机/端口组合与.net regex -端口部分可选
本文关键字:口部 regex 主机 组合 提取 net | 更新日期: 2023-09-27 17:54:04
假设我想从如下字符串中提取主机名和端口号:
stackoverflow.com: 443
这很简单。我可以这样做:
(?<host>.*):(?<port>'d*)
我不担心协议方案或有效的主机名/ip地址或tcp/udp端口,这对我的请求不重要。
但是,我还需要支持一个超出正则表达式知识范围的变化——不带端口的主机名: stackoverflow.com我想为此使用单个正则表达式,并且我想使用命名捕获组,这样主机组将始终存在于正匹配中,而端口组存在当且仅当我们有一个冒号后跟一些数字。
我试图从我对它的微弱理解中做一个积极的回顾:
(?<host>.*)(?<=:)(?<port>'d*)
这个比较接近,但是冒号(:)包含在主机捕获的末尾。所以我试着改变主机,包括除了冒号以外的任何内容,像这样:
(?<host>[^:]*)(?<=:)(?<port>'d*)
这给了我一个空的主机捕获。
关于如何实现这一点的任何建议,即使冒号和端口号可选,但如果它们存在,包括端口号捕获并使冒号"消失"?
编辑:我收到的所有四个答案对我来说都很好,但要注意其中一些的评论。我接受了sln的答案,因为它有很好的布局和对regexp结构的解释。感谢所有的回复!
我建议使用Uri类代替正则表达式。
// Use URI class for parsing only
var uri = new Uri("http://" + fullAddress);
// get host
host = uri.DnsSafeHost;
// get port
portNum = (ushort)uri.Port;
好处是
- 它支持:
- IPv4和IPv6 国际化域名(IDN)
查看在。net上使用的示例
这可能是(?<host>[^:]+)(?::(?<port>'d+))?
(?<host> [^:]+ ) # (1), Host, required
(?: # Cluster group start, optional
: # Colon ':'
(?<port> 'd+ ) # (2), Port number
)? # Cluster group end
edit -如果您不使用集群组,而是使用捕获组作为集群组,这就是Dot-Net在其默认配置状态下"计数"组的方式-
(?<host> [^:]+ ) #_(2), Host, required
( # (1 start), Unnamed capture group, optional
: # Colon ':'
(?<port> 'd+ ) #_(3), Port number
)? # (1 end)
如果您的主机名不包含:
,如ipv64,那么试试这个:
(?<host>[^:]*):?(?<port>'d*)
试试这个:
(?<host>[^:]+)(:(?<port>'d+))?
这使得整个冒号和端口号部分成为可选组,并捕获其中的端口号。另外,我使用加号来确保主机名和端口号至少包含一个字符。
你可以这样做:
(?<host>[^:]+)(:(?<port>''d+))?