如何才能使此正则表达式匹配正确?

时间:2009-10-25 23:19:44

标签: c# regex

鉴于此正则表达式:

^((https?|ftp):(\/{2}))?(((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}
(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))|(((([a-zA-Z0-9]+)(\.)*?))(\.)([a-z]{2}
|com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|museum){1})

为便于阅读而重新格式化:

@"^((https?|ftp):(\/{2}))?" + // http://, https://, ftp:// - Protocol Optional
@"(" + // Begin URL payload format section
@"((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" + // IPv4 Address support
@")|("+ // Delimit supported payload types
@"((([a-zA-Z0-9]+)(\.)*?))(\.)([a-z]{2}|com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|museum){1}" + // FQDNs
@")"; // End URL payload format section

如何在此“失败”测试用例中使其失败(即不匹配)?

http://www.google

当我在TLD部分指定{1}时,我认为没有扩展名会失败。我错了吗?

编辑:这是我的通行证条件:

这些是我失败的条件:

5 个答案:

答案 0 :(得分:4)

我会抛出另一个建议。您可能希望结合使用内置System.Uri类的解析和几个有针对性的正则表达式(或适当时的简单字符串检查)。

示例:

string uriString = "...";

Uri uri;
if (!Uri.TryCreate(uriString, UriKind.Absolute, out uri))
{
    // Uri is totally invalid!
}
else
{
    // validate the scheme
    if (!uri.Scheme.Equals("http", StringComparison.OrdinalIgnoreCase))
    {
        // not http!
    }

    // validate the authority ('www.blah.com:1234' portion)
    if (uri.Authority // ...)
    {
    }

    // ...
}

答案 1 :(得分:3)

有时,一个全能的需求并不是最好的解决方案,无论多么诱人。虽然调试这个正则表达式是可行的(参见Greg Hewgills的回答),但考虑对不同类别的问题进行一些测试,例如:一个数字地址测试和一个命名地址测试。

答案 2 :(得分:2)

你需要强制你的正则表达式匹配,直到字符串结束。在其最后添加$。否则,你的正则表达式可能只匹配http://,或者比整个字符串短的其他东西。

答案 3 :(得分:1)

“验证网址”问题已经解决了很多次。我建议你使用System.Uri类,它可以验证更多的情况,而不是你可以动摇一下。

如果验证失败,代码Uri uri = new Uri("http://whatever");会抛出UriFormatException。这可能就是你想要的。

*)或​​者解决了。定义什么是有效网址实际上非常棘手。

答案 4 :(得分:0)

关于定义,“有效网址”应该在您进行DNS查找时为您提供IP地址。 IP应该连接到,当发出请求时,您会收到可以使用的HTML信息形式的回复。

所以我们要找的是“有效的网址格式”,这就是system.uri非常方便的地方。但是,如果URL隐藏在一大块tekst中,您首先要找到一些验证为有效URL格式的内容。

将URL与任何给定的可读tekst区分开来的是点后面没有空格。 “123.com”可以验证为真实的URL。

使用正则表达式

[a-z_\.\-0-9]+\.[a-z]+[^ ]*

在文本中找到任何可能的有效网址,然后执行system.uri检查以查看其是否为有效的网址格式,然后进行查找。只有当查找为您提供结果时,您才知道该URL有效。