不匹配某些扩展名的正则表达式模式?

13

我写了这个模式

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

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

它可以正确地处理(不匹配)filename.jpg。我正在尝试找出如何使其不匹配任何包含2个或更多点的文件,即使文件名长度可变。我尝试使用后顾断言,但python会抱怨没有使用固定宽度(我不太确定这是什么意思,但文件名将具有可变长度。)

5个回答

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

有人可以解释一下这个正则表达式吗? - user2514157
有人能解释一下这个正则表达式吗? - user2514157
@user2514157 你可以看一下负向先行断言,那里有几乎等效的示例。 - bereal

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标签以防止混淆。 - paradigm111
你的正则表达式似乎是试图排除包含.jpg..png.的字符串,但我认为想法是要排除任何以.jpg.png结尾的内容。OP的正则表达式失败了,因为前瞻和最终的.+$都可以在file.name.jpg中的第一个.之后匹配。将其更改为[^.]+$,如@bereal所做的那样,强制前瞻仅适用于最终的点-任何序列。 - Alan Moore

2
如果你只关心字符串不以.jpg.png结尾,你可以使用以下代码:
^.+$(?<!\.jpg)(?<!\.png)

^.+并不是必须的,但根据JSON解析器的编码方式,您可能需要强制正则表达式消耗整个字符串。如果您还将正则表达式用于其他验证,您可能需要更复杂的内容,例如:

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

你可能尝试使用(?<!\.jpg|\.png),但这种方法在Python的正则表达式中不起作用。因为Python的正则表达式是最严格的之一,特别是当它涉及到回顾后发表达式时。PHP和Ruby 1.9+可以接受它,因为每个备选项都有一个固定的长度。它们甚至不必是相同的长度; (?<!\.jpg|\.jpeg|\.png)也可以工作。只是不要尝试将点因素分离出来,例如(?<!\.(?:jpg|jpeg|png)); 备选项必须位于回顾后发表达式的顶层。

Java可以接受分解版本,因为它在编译时会做更多的工作来确定回顾后发表达式可能需要匹配的最大字符数。然而,回顾后发表达式的表达式需要相当简单,并且不能使用+*限定符。最后,.NET和JGSoft正则表达式没有对回顾后发表达式施加任何限制。但是,当Python无法确定回顾后发表达式需要匹配的确切字符数时,它会生成那个晦涩的错误消息。


1

看起来你差不多做到了:

.*\.(?!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

如果这不是您想要的,请更新您的问题并说明您的期望。


0
请尝试:
    .*\.(jpg$|png$)
它将正确匹配 filename.jpg。您正在尝试找出如何匹配任何 .jpg 文件,即使文件名中有2个或更多点,也可以正常工作。
在使用Python脚本时,请确保使用正确类型的分割。 不同类型的分割包括rsplit(右分割)和lsplit(左分割)。

你搞反了:正则表达式不应该匹配 filename.jpg 或者 file.name.png。我猜 filename.txt 或者 file.name.foo 是可以的。 - Alan Moore

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接