我需要一个正则表达式模式来匹配不以这样的序列结尾的字符串:
\.[A-z0-9]{2,}
我的意思是,被检查的字符串在其末尾不能有一个点序列,然后是两个或多个字母数字字符。例如,字符串
/home/patryk/www
and 也
/home/patryk/www/
应该匹配所需的模式
/home/patryk/images/DSC002.jpg
而不应该匹配。我想这与环视(前瞻)有关,但我仍然不知道如何做到这一点。任何帮助表示赞赏。
4 回答
旧答案
如果您的正则表达式支持它,您可以在最后使用否定的lookbehind:
^.*+(?<!\.\w{2,})$
这将匹配一个字符串,该字符串的结束锚点前面没有您不想要的 icky 序列。
请注意,正如 m.buettner 所指出的,这使用了无限长度的后视,这是 .NET 独有的功能
新答案
然而,经过一番挖掘,我发现可变长度的前瞻得到了相当广泛的支持,所以这里有一个使用这些的版本:
^(?:(?!\.\w{2,}$).)++$
在对答案的评论中,您已声明您不想匹配末尾带有正斜杠的字符串,这是通过简单地在前瞻中添加正斜杠来完成的。
^(?:(?!(\.\w{2,}|/)$).)++$
请注意,我使用\w
的是简洁,但它允许下划线通过。如果这很重要,您可以将其替换为[^\W_]
.
Asad 的版本非常方便,但只有 .NET 的正则表达式引擎支持可变长度的后视(这是为什么每个正则表达式问题都应该包含所使用的语言或工具的众多原因之一)。
如果我们考虑应该匹配的可能情况,我们可以将其减少为固定长度的后视(大多数引擎都支持,除了 JavaScrpit)。这将是末尾的一个或零个字母/数字(无论是否前面.
)或两个或多个前面没有点的字母/数字。
^.*(?:(?<![a-zA-Z0-9])[a-zA-Z0-9]?|(?<![a-zA-Z0-9.])[a-zA-Z0-9]{2,})$
这应该这样做:
^(?:[^.]+|\.(?![A-Za-z0-9]{2,}$))+$
它交替匹配一个或多个除点之外的任何内容,或者如果后面没有两个或多个字母数字字符和字符串结尾的点,则它会交替匹配。
编辑:升级它以满足新的要求是一样的:
^(?:[^./]+|/(?=.)|\.(?![A-Za-z0-9]{2,}$))+$
打破它,我们有:
[^./]+
# 一个或多个任意字符,除了.
or/
/(?=.)
# 一个斜线,只要后面至少有一个字符\.(?![A-Za-z0-9]{2,}$)
# 一个点,除非它后跟两个或多个字母数字字符,然后是字符串的结尾
另一方面:[A-z]
是一个错误。 它匹配所有大写和小写 ASCII 字母,但也匹配字符[
, ]
, ^
, _
, 反斜杠和反引号,它们的代码点恰好位于Z
和之间a
。
很少支持可变长度后视,但您不需要:
^.*(?<!\.[A-z0-9][A-z0-9]?)$