在正则表达式中选择可能的最大出现次数

时间:2013-05-01 13:03:00

标签: c# regex

我想从文本中提取带有端口的IP地址。

但我不知道如何让正则表达式捕获最大可能的数字匹配(IP八位字节)。例如,从209和表达式\ d {1,3}来捕获整个209而不是仅仅9。

Regex rgx = new Regex(@".*(?<ip>(?:[12]?\d{1,2}\.){3}[12]?\d{1,2})\s*(?<port>\d{2,4}).*");
string textWithIPs = "209.90.238.251    3128    HTTPS   Anonymous   [United States Proxy] United States Washington  Renton  84.5%   58.240.224.186  80  HTTP    None    [China Proxy] China Jiangsu Nanjing 98.4%   ";

foreach (Match m in rgx.Matches(textWithIPs))
{
    MessageBox.Show("ip: " + m.Groups["ip"].Value + " port: " + m.Groups["port"].Value);
}

预期产出:

ip: 209.90.238.251 port: 3128
ip: 58.240.224.186 port: 80

1 个答案:

答案 0 :(得分:3)

正则表达式开头的.*会消耗您要匹配的文字,而最后的.*只是多余的。删除它们,您的代码应该可以正常工作。

您当前的正则表达式可能与没有端口号的单独IP地址匹配,并且错误地将其拆分。你可以给它输入字符串123.123.123.123,输出的IP是123.123.123.1,端口号是23,这是不正确的 1 。我将\s*更改为\s+以解决此问题。

@"(?<ip>(?:[12]?\d{1,2}\.){3}[12]?\d{1,2})\s+(?<port>\d{2,4})"

请注意,端口号的范围是1到65535(端口0是保留的),因此您可能希望将端口的正则表达式从(?<port>\d{2,4})修改为(?<port>\d{1,5})

脚注

1 这是您在开头删除.*后的输出。在您的原始正则表达式中,问题仍然存在 - 最后2位仍然被切断以形成端口号,这是不正确的。