否定前瞻正则表达式

gil*_*ly3 64 javascript regex regex-lookarounds

我希望匹配以".htm"结尾的所有字符串,除非它以"foo.htm"结尾.我对正则表达式一般都很体面,但负面的前瞻让我难过.为什么这不起作用?

/(?!foo)\.htm$/i.test("/foo.htm");  // returns true. I want false.
Run Code Online (Sandbox Code Playgroud)

我应该用什么呢?我想我需要一个"负面看后面 "的表达式(如果JavaScript支持这样的东西,我知道它没有).

rid*_*ner 92

问题非常简单.这样做:

/^(?!.*foo\.htm$).*\.htm$/i

  • 你能解释发生了什么吗?我看到您有一个行标记(^)的开始,但有两个行标记($)的结尾。这如何使负面的前瞻性发挥作用? (5认同)

Nic*_*ole 18

你所描述的(你的意图)是一个消极的后视,Javascript不支持后视.

向前看从它们所处的角色向前看 - 你已经把它放在了它之前..所以,你所拥有的实际上是说" .htm只要从该位置开始的前三个字符(.ht)不是foo"总是如此,那么任何结尾都是正确的.

通常,负面观察的替代品是匹配超过您需要的,并且仅提取您实际需要的部分.这很hacky,根据你的确切情况你可能会想出其他东西,但是这样的事情:

// Checks that the last 3 characters before the dot are not foo:
/(?!foo).{3}\.htm$/i.test("/foo.htm"); // returns false 
Run Code Online (Sandbox Code Playgroud)

  • +1优秀的解释.但是,`/(?!foo).{3}\.htm $/i`将无法匹配少于三个字符的名称,即`a.htm`.这是一个可以得到所有的东西:`/ ^(?!.*foo\.htm $).*\.htm $/i` (4认同)