【问题标题】:Regex pattern that does not match certain extensions?与某些扩展不匹配的正则表达式模式?
【发布时间】:2012-04-07 05:24:04
【问题描述】:

我写了这个模式

^.*\.(?!jpg$|png$).+$

但是有一个问题 - 这个模式匹配 file.name.jpg(2 点)

它在 filename.jpg 上正常工作(不匹配)。我试图弄清楚如何使它不匹配任何 .jpg 文件,即使文件名中有 2 个或更多点。我尝试使用向后看,但 python 抱怨没有使用固定宽度(我不确定这意味着什么,但文件名将是可变长度。)

【问题讨论】:

    标签: python regex lookbehind


    【解决方案1】:

    这应该可以工作:^.*\.(?!jpg$|png$)[^.]+$

    【讨论】:

      【解决方案2】:

      如果你只关心字符串不以.jpg 或.png 结尾,你可以使用这个:

      ^.+$(?<!\.jpg)(?<!\.png)
      

      ^.+ 不是绝对必要的,但根据 JSON 解析器的编码方式,您可能需要强制正则表达式使用整个字符串。如果您也将正则表达式用于其他验证,您可能需要更详细的内容,例如:

      ^\w+(?:\.\w+)+$(?<!\.jpg)(?<!\.png)
      

      您可能尝试过使用(?&lt;!\.jpg|\.png),但它不起作用,因为Python 的正则表达式风格是最严格的lookbehinds 之一。 PHP 和 Ruby 1.9+ 会接受它,因为每个替代品都有固定的长度。它们甚至不必是相同的长度; (?&lt;!\.jpg|\.jpeg|\.png) 也可以。只是不要试图分解点,如(?&lt;!\.(?:jpg|jpeg|png));交替必须在后视的顶层。

      Java 会接受分解后的版本,因为它在编译时会做更多的工作来确定后向可能需要匹配的最大字符数。不过,lookbehind 表达式需要相当简单,并且不能使用+ 或* 量词。最后,.NET 和 JGSoft 风格对后视完全没有限制。但是 Python 做了一个非常简单的尝试来确定后向需要匹配的确切字符数,并在失败时生成那个神秘的错误消息。

      【讨论】:

        【解决方案3】:

        使用os.path 的漂亮函数将文件路径正确拆分为组件以便于解析:

        filepath, filename = os.path.split(str)
        basename, extension = os.path.splitext(filename)
        
        if exension[1:] in ['jpg', 'png']:
          # The extension matches
        

        试试这个正则表达式(不要这样做。它与你想做的完全相反):

        \.(jpg|png)([^\.]|$)
        

        【讨论】:

        • 我无法访问 Python,它是 Python 的正则表达式引擎,但我只能访问 JSON 配置文件以将正则表达式放在 Python 程序中。我删除了 Python 标记以防止混淆。
        • 您的正则表达式似乎试图排除 包含 .jpg. 或 .png. 的字符串,但我相信这个想法是排除任何 结束 i> 与.jpg 或.png。 OP 的正则表达式失败,因为前瞻和最终的.+$ 可以在file.name.jpg 中的第一个. 之后匹配。将其更改为[^.]+$,就像@bereal 所做的那样,强制前瞻仅适用于最终的点序列。
        【解决方案4】:

        看起来你几乎拥有它:

        .*\.(?!jpg$|png$)[^.]+
        

        根据我的测试(在 java 中),我得到了这些结果:

        file.jpg - false
        file.png - false
        file.name.jpg - false
        file.name.png - false
        file.gif - true
        file.name.gif - true
        file.jpg.gif - true
        file.jpge - true
        

        如果这不是您想要的,请根据您的期望更新您的问题。

        【讨论】:

          【解决方案5】:

          请尝试

          .*\.(jpg$|png$)

          它将正确匹配 filename.jpg。您试图弄清楚如何匹配任何 .jpg 文件,即使文件名中有 2 个或更多点,也可以正常工作。
          在使用 python 脚本时,请确保您使用的是正确的拆分类型。 不同类型的拆分即rsplit(右拆分)和lsplit(左拆分)。

          【讨论】:

          • 你搞错了:正则表达式不应该匹配 filename.jpg 或 file.name.png。 filename.txt 或 file.name.foo 没问题,我想。
          猜你喜欢
          • 2015-08-05
          • 1970-01-01
          • 2016-05-19
          • 2019-10-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多