【问题标题】:Regular expression to filter out URLs with a literal dot after the last slash正则表达式过滤掉最后一个斜线后带有文字点的 URL
【发布时间】:2015-11-05 18:48:31
【问题描述】:

我需要正则表达式来识别最后一个正斜杠之后的网址

  • 有一个文字点,例如

    http://www.example.es/cat1/cat2/some-example_DH148439#.Rh1-js_4
    
  • 没有文字点,例如

    http://www.example.es/cat1/cat2/cat3
    

到目前为止,我只找到了匹配 ^(.*[\\\/]) 之前或最后一个正斜杠之后的所有内容的正则表达式:[^/]+$ 以及匹配最后一个斜杠 (?!.*\.)(.*) 之后的文字点之后的所有内容但是我无法想出来上面的,请帮忙。

【问题讨论】:

  • 如果这是请求的 URL,那么片段标识符(即 # 之后的所有内容,例如 .Rh1-js_4)实际上并未传递给服务器,因此您无法检查此服务器-边。 (?)

标签: python regex


【解决方案1】:

嗯,像往常一样,使用正则表达式匹配 URL 是错误工作的错误工具。您可以使用urlparse(或python3 中的urllib.parse)以非常Python 的方式完成这项工作:

>>> from urlparse import urlparse
>>> urlparse('http://www.example.es/cat1/cat2/some-example_DH148439#.Rh1-js_4')
ParseResult(scheme='http', netloc='www.example.es', path='/cat1/cat2/some-example_DH148439', params='', query='', fragment='.Rh1-js_4')
>>> urlparse('http://www.example.es/cat1/cat2/cat3')
ParseResult(scheme='http', netloc='www.example.es', path='/cat1/cat2/cat3', params='', query='', fragment='')

如果你真的想要一个正则表达式,下面的正则表达式就是一个可以回答你问题的例子:

import re
>>> re.match(r'^[^:]+://([^.]+\.)+[^/]+/([^/]+/)+[^#]+(#.+)?$', 'http://www.example.es/cat1/cat2/some-example_DH148439#.Rh1-js_4') != None
True
>>> re.match(r'^[^:]+://([^.]+\.)+[^/]+/([^/]+/)+[^#]+(#.+)?$', 'http://www.example.es/cat1/cat2/cat3') != None
True

但我提供的正则表达式足以回答您的问题,但不是验证 URL 或将其拆分为多个部分的好方法。我想说它唯一的兴趣是实际回答你的问题。

这是正则表达式生成的自动机,以便更好地理解它:

请注意您的问题,因为 JL 的正则表达式不匹配:

http://www.example.es/cat1/cat2/cat3

在重读您的问题 3 次后,您实际上是在要求以下正则表达式:

\/([^/]*)$

这将匹配您的两个示例:

http://www.example.es/cat1/cat2/some-example_DH148439#.Rh1-js_4
http://www.example.es/cat1/cat2/cat3

@jl-peyret 建议的只是如何匹配/ 之后的一个小点,这会生成以下自动机:

所以,无论你真正想要什么:

  1. 尽可能使用 urlparse 来匹配 URL 的各个部分
  2. 如果您尝试定义 django 路由,那么尝试匹配片段是没有希望的
  3. 下次您提出问题时,请务必准确,并举例说明您的尝试:帮助我们帮助您。

【讨论】:

  • 为什么不能在 django 中工作?除了片段部分仅在客户端使用这一事实之外,OP 的问题非常明确:他想要匹配 URL。我不是想猜测 OP 试图做什么,@w3d 已经对片段部分将被吃掉的事实发表了评论。
  • 我的意思是,在 django 路由中,您 需要 使用正则表达式。否则在 / 上拆分,后跟 .检查就可以了。
  • 确实,虽然这不是 OP 所要求的,但无论他实际要求的是什么……
  • 嗯,我不同意这个老笑话,有时程序员从一个问题开始解决并使用正则表达式现在有两个问题......顺便说一句,我确实测试了我的正则表达式 匹配他的 cat2/cat3,但我真的无法从这个问题中弄清楚你如何要求一个都需要一个 '.' 的正则表达式。而且也不在乎是否有'。所以我以为他忘了提到 cat2/cat3 应该是 not 匹配的。问题:你从哪里得到你的状态图?我经常可以在正则表达式上使用帮助。
  • 有人写了debuggex.com 这很棒,试试看,你可以通过图表运行你的正则表达式,这很有趣。虽然它不是状态图,它是一个自动机,更准确地说是一个NFA。要了解更多信息,我有一个关于正则表达式的旧答案,我在其中给出了 a few useful resources,您可能想阅读。 ;-)
【解决方案2】:
\/([^\/]*\.+[^\/]*)$

第一个 / 迫使你照顾它。 $ 强制结束字符串和 两个类否定都避免了任何/之间。 检查@https://regex101.com/

【讨论】:

    【解决方案3】:

    我会像这样使用前瞻

    (?=.*\.)([^/]+$)
    

    Demo

    (?=             # Look-Ahead
      .             # Any character except line break
      *             # (zero or more)(greedy)
      \.            # "."
    )               # End of Look-Ahead
    (               # Capturing Group (1)
      [^/]          # Character not in [/] Character Class
      +             # (one or more)(greedy)
      $             # End of string/line
    )               # End of Capturing Group (1)
    

    或者像这样的负面预测

    (?!.*\.)([^/]+$)
    

    相反的情况

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-15
      • 2019-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多