【问题标题】:How can I make this regex match correctly?我怎样才能使这个正则表达式正确匹配?
【发布时间】:2009-10-25 23:19:44
【问题描述】:

鉴于此正则表达式:

^((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} 时,我认为如果没有扩展名它会失败。我错了吗?

编辑:这些是我的 PASS 条件:

这些是我的失败条件:

【问题讨论】:

  • 那个正则表达式是病态的。 C# 没有 URL 验证机制吗?我知道PHP可以。这也是对有效 URL 的不完整检查(例如,有限的 TLD,1000000000 是点符号的替代方法,用户名的使用(可选密码)等)。这个复杂的正则表达式真的有必要吗?
  • 您的正则表达式也无法匹配un.int。 :)
  • @Cletus:谷歌搜索显示 C# 中的大多数 URL 验证都是通过正则表达式完成的。
  • @Greg:根据regextester.com,它确实匹配 un.int,尽管当我查看 TLD 部分中的 {2} 时这让我感到困惑......奇怪......
  • 非美国网址怎么样 *.co.uk *.com.au 等

标签: c# regex


【解决方案1】:

我会提出一个替代建议。您可能希望结合使用内置 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 // ...)
    {
    }

    // ...
}

【讨论】:

    【解决方案2】:

    有时,一个包罗万象的 reqex 并不是最好的解决方案,但也很诱人。虽然调试此正则表达式是可行的(请参阅 Greg Hewgills 的回答),但请考虑对不同类别的问题进行一些测试,例如一项针对数字地址的测试,一项针对命名地址的测试。

    【讨论】:

      【解决方案3】:

      您需要强制您的正则表达式匹配到字符串的末尾。在它的最后添加一个$。否则,您的正则表达式可能只是匹配 http://,或者比您的整个字符串短的其他内容。

      【讨论】:

      • 当我这样做时,它会失败(实际上是正确的,但经过编辑,所以 MarkDown 显示它正确):http www.zi255.com?Req=Post&Post=4
      • 这不是您问题的一部分!我认为您需要更仔细地指定您希望正则表达式匹配的内容,同样重要的是,您希望它匹配的内容。
      • 抱歉,为了清楚起见,添加了我的测试条件。
      • +1,因为这确实解决了(糟糕)说明的原始问题。
      【解决方案4】:

      “验证 url”问题已解决*多次。我建议你使用System.Uri 类,它验证的案例比你可以动摇的要多。

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

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

      【讨论】:

        【解决方案5】:

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

        所以我们正在寻找“有效的 URL 格式”,这就是 system.uri 派上用场的地方。但是,如果 URL 隐藏在一大块 tekst 中,您首先需要找到可以验证为有效 URL 格式的内容。

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

        使用正则表达式

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-01-19
          • 2011-12-05
          相关资源
          最近更新 更多