说我想从这样的字符串中提取主机名和端口号:
stackoverflow.com:443
这很简单。我可以这样做:
(?<host>.*):(?<port>\d*)
我不担心协议方案或有效的主机名/ IP地址或tcp / udp端口,这对我的请求并不重要。
但是,我还需要支持一种扭曲,这种扭曲超出了我对正则表达式的了解 - 没有端口的主机名:
stackoverflow.com
我想为此使用单个正则表达式,并且我想使用命名捕获组,以便主机组始终以正匹配存在,而当且仅当我们有冒号后跟端口组才存在一些数字。
我试图通过对它的微弱理解做出积极的观察:
(?<host>.*)(?<=:)(?<port>\d*)
这很接近,但冒号(:)包含在主机捕获结束时。所以我试图改变主机,除了像这样的冒号:
(?<host>[^:]*)(?<=:)(?<port>\d*)
这给了我一个空主机捕获。
有关如何实现此目的的任何建议,即使冒号和端口号可选,但如果它们在那里,包括端口号捕获并使冒号“消失”?
编辑:我收到的所有四个答案都适用于我,但要注意其中一些答案。由于regexp结构的良好布局和解释,我接受了sln的答案。感谢所有回复!
答案 0 :(得分:4)
我建议使用Uri class而不是正则表达式。
// Use URI class for parsing only
var uri = new Uri("http://" + fullAddress);
// get host
host = uri.DnsSafeHost;
// get port
portNum = (ushort)uri.Port;
好处是
请参阅.NET Fiddle
上的使用示例答案 1 :(得分:2)
这可能是(?<host>[^:]+)(?::(?<port>\d+))?
(?<host> [^:]+ ) # (1), Host, required
(?: # Cluster group start, optional
: # Colon ':'
(?<port> \d+ ) # (2), Port number
)? # Cluster group end
编辑 - 如果您不使用群集组,并使用捕获组作为该群集组,则这就是Dot-Net&#34;计数&#34;处于默认配置状态的组 -
(?<host> [^:]+ ) #_(2), Host, required
( # (1 start), Unnamed capture group, optional
: # Colon ':'
(?<port> \d+ ) #_(3), Port number
)? # (1 end)
答案 2 :(得分:1)
如果您的主机名不包含:
,例如ipv64,请尝试以下方法:
(?<host>[^:]*):?(?<port>\d*)
答案 3 :(得分:1)
试试这个:
(?<host>[^:]+)(:(?<port>\d+))?
这使得整个冒号和端口号部分成为可选组,并捕获其中的端口号。另外,我使用加号来确保主机名和端口号至少包含一个字符。
答案 4 :(得分:1)
您可以使用:
(?<host>[^:]+)(:(?<port>\\d+))?