我写了这个模式
^.*\.(?!jpg$|png$).+$
但是有一个问题 - 这个模式会匹配到file.name.jpg(两个点)
它可以正确地处理(不匹配)filename.jpg。我正在尝试找出如何使其不匹配任何包含2个或更多点的文件,即使文件名长度可变。我尝试使用后顾断言,但python会抱怨没有使用固定宽度(我不太确定这是什么意思,但文件名将具有可变长度。)
我写了这个模式
^.*\.(?!jpg$|png$).+$
但是有一个问题 - 这个模式会匹配到file.name.jpg(两个点)
它可以正确地处理(不匹配)filename.jpg。我正在尝试找出如何使其不匹配任何包含2个或更多点的文件,即使文件名长度可变。我尝试使用后顾断言,但python会抱怨没有使用固定宽度(我不太确定这是什么意思,但文件名将具有可变长度。)
^.*\.(?!jpg$|png$)[^.]+$
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)([^\.]|$)
.jpg.
或.png.
的字符串,但我认为想法是要排除任何以.jpg
或.png
结尾的内容。OP的正则表达式失败了,因为前瞻和最终的.+$
都可以在file.name.jpg
中的第一个.
之后匹配。将其更改为[^.]+$
,如@bereal所做的那样,强制前瞻仅适用于最终的点-任何序列。 - Alan Moore.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无法确定回顾后发表达式需要匹配的确切字符数时,它会生成那个晦涩的错误消息。
看起来你差不多做到了:
.*\.(?!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
如果这不是您想要的,请更新您的问题并说明您的期望。
.*\.(jpg$|png$)它将正确匹配 filename.jpg。您正在尝试找出如何匹配任何 .jpg 文件,即使文件名中有2个或更多点,也可以正常工作。
filename.jpg
或者 file.name.png
。我猜 filename.txt
或者 file.name.foo
是可以的。 - Alan Moore