【问题标题】:Capture domain and path from URL with regex使用正则表达式从 URL 捕获域和路径
【发布时间】:2014-02-24 17:53:27
【问题描述】:

我正在尝试编写一个从 URL 捕获域和路径的正则表达式。我试过了:

https?:\/\/(.+)(\/.*)

这适用于http://example.com/foo

Match 1
0.  google.com
1.  /foo

但不是我对http://example.com/foo/bar 的期望:

预期:

Match 1
0.  google.com
1.  /foo/bar

实际:

Match 1
0.  google.com/foo
1.  /bar

我做错了什么?

【问题讨论】:

  • 你有什么理由想用正则表达式来做这件事吗?标准库中的 urlparse 模块可以做到这一点以及更多。
  • @DanielRoseman urlparse 在分解 URL 方面做得很好,但我想要包含查询、参数和片段的路径。这对其他情况很有用。谢谢!

标签: python regex


【解决方案1】:

如上所述 - 这是一个非网格版本:https?:\/\/(.+?)(\/.*)

【讨论】:

    【解决方案2】:

    https?:\/\/(.+)(\/.*)

    我做错了什么?

    +greedy。您应该在 [^/] 上使用它而不是点。

    还请注意,您的“路径”部分还将包含查询字符串和片段(哈希)。

    这个只获取域(+登录名、密码、端口)和路径(没有查询字符串或片段)。

    ^https?://([^/]+)(/[^?#]*)?
    

    我将相应地转义斜线留给你。

    警告:这需要一个有效的 URI,因此它是好的,并解析权限和路径部分。如果你想按照标准解析一个URI,你需要实现整个语法或者从RFC 2396的§8获取官方的正则表达式。

    以下行是用于分解 URI 的正则表达式 引用到它的组件。

       ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
        12            3  4          5       6  7        8 9
    

    上面第二行的数字只是为了便于阅读; 它们指示每个子表达式的参考点(即,每个 双括号)。我们指的是子表达式匹配的值 作为$。例如,将上面的表达式匹配到

       http://www.ics.uci.edu/pub/ietf/uri/#Related
    

    导致以下子表达式匹配:

       $1 = http:
       $2 = http
       $3 = //www.ics.uci.edu
       $4 = www.ics.uci.edu
       $5 = /pub/ietf/uri/
       $6 = <undefined>
       $7 = <undefined>
       $8 = #Related
       $9 = Related
    

    其中表示组件不存在,原样 上例中查询组件的情况。因此,我们 可以将四个组件和fragment的值确定为

       scheme    = $2
       authority = $4
       path      = $5
       query     = $7
       fragment  = $9
    

    【讨论】:

    • 不需要 \/[^?]* 部分,因为该类将匹配域之后的第一个 /。如果你需要它,如果字符串中没有它,正则表达式将失败。
    • @sln 不久前(几周)我在 RFC 中查找了它。域(和可选端口号)后的斜杠是强制性的。如果任何 URL 没有它……那么,它不是 URL。如果您想尽可能宽容,请将其更改为(\/[^?]*)?
    • 它是一个坚持不懈的人。如果是^https?://([^/]+)([^?]*),则捕获组 2 的第一个字符只能是 /,否则捕获组 1 将捕获到字符串的末尾,而捕获组 2 为空。我同意你的观点,但是当你可以检查第 2 组的长度并且仍然可以获得有关域的一些信息时,为什么正则表达式会失败。
    • @sln 在这种情况下为真,因为正则表达式引擎永远不需要回溯。但是在那里写斜线仍然更清楚。我认为不能立即进行回溯并不是很明显,如果已经完成,第一组不需要在斜线之前立即结束。需要Possessive + (++)。
    • @sln 我在 2014 年 1 月 4 日阅读了RFC 1738,现在我意识到我忘记了它在说什么。 §3.1 和更明确的 §3.3 说端口和路径之间的斜杠不是路径的一部分,当且仅当有某些内容(路径或查询字符串)时才需要。片段(哈希)不是 URL 的一部分,标准没有提及它。它是 URI 参考的一部分,在 URI 标准 RFC 2396 中定义。现在阅读它的§3,我意识到一些事情发生了变化。斜杠现在是路径的一部分,即使查询字符串不是,也可以省略。
    【解决方案3】:

    类似这种“贪婪”版本的东西可能会起作用。我不知道 Python 是否需要分隔符,所以这只是原始的正则表达式。

     #   https?://([^/]+)(.*)
    
     https?://
     ( [^/]+ )           # (1)
     ( .* )              # (2)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-29
      • 1970-01-01
      • 2014-04-30
      • 1970-01-01
      • 2017-01-30
      相关资源
      最近更新 更多