是否存在“[^ xy]”不等于“(?!x | y)”的情况。

时间:2013-06-27 20:31:02

标签: javascript regex

我正在使用自己的JavaScript库来支持正则表达式的新元字符和功能,我想找到[^xy]不等同于(?!x).的情况(或者更具体地说(?:(?!x|y).))。

以示例文字:"abc\n"

为例

说我想模仿Perl正则表达式:/\A.{3}\Z/s

使用单行标记时,JavaScript正则表达式应相当于:/^[\s\S]{3}\n*$(?!\s)/\A变为^.变为[\s\S],{{1} }变成\Z

现在,\n*$(?!\s)会失败,但/^.{3}$/会捕获“abcabc”(与Perl正则表达式相同)

由于/^[\s\S]{3}\n*$(?!\s)/不仅包含元字符,因此仿真\Z似乎更难。

以示例文字:[^\Z]

为例

Perl正则表达式"abcabc\n"的拟议JavaScript正则表达式为/.{3}[^\Za]/g

两者都匹配.{3}(?:(?!\n*$(?!\s)|a).)/g

所以,最后,我再次提出问题。是否存在"bcab"[^xy]不等同于这种情况的情况,可能是在更复杂的正则表达式中,前瞻会改变场景?

5 个答案:

答案 0 :(得分:9)

对于输入字符串"x\na",2个正则表达式提供不同的输出,因为.与换行符不匹配。

console.log("x\na".match(/(?:(?!x|y).)/))
["a", index: 2, input: "x↵a"]
console.log("x\na".match(/[^xy]/))
["↵", index: 1, input: "x↵a"]

如果您将.更改为[\s\S],则在这种情况下输出相同:

console.log("x\na".match(/(?:(?!x|y)[\s\S])/))
["↵", index: 1, input: "x↵a"]

我现在想不出任何其他情况。

答案 1 :(得分:5)

  

是否存在[^xy]不等于(?!x|y).的情况?

只有您已经描述的那个:JS点与换行符不匹配,需要替换为[\s\S]

  

\Z变为\n$(?!\s)

看起来不对劲。在字符串结束后(\z / $),无论是否有空格,都不会有任何内容。 Afaik,\Z是一个零宽度断言(它不消耗换行符)并且应该等同于

(?=\n*$)
//   ^ not sure whether ? or *
  

由于\Z不仅包含元字符,因此仿真[^\Z]似乎更难。

“元字符”是什么意思?这是一个零宽度断言,在字符类中没有多大意义。我猜这是一个语法错误,或者将字面解释(未转义)为[^Z]

答案 2 :(得分:4)

[^xy]将与\n匹配。默认情况下,(?!x|y).\n不匹配(因为.\n不匹配)

我不相信javascript有“dotall”或“单行”修饰符,但是每个浏览器的新版本每隔几个月就会出现一次,我已经失去了轨道。

答案 3 :(得分:0)

正如其他人所说,您应该在替换中使用[\s\S]而不是.。否则,如果你只是通过文字字符串进行转换,还有一些事情要处理。特别是元字符和转义序列:

[^*)] => (?!\*|\))[\s\S]

但我想你无论如何都需要专门解析和编写元字符。

最棘手的可能是\b,因为它是字符类中的字符(退格)和外部的单词边界。所以在替换中,你必须使用八进制或十六进制转义:

[^a\b] => (?!a|\10)[\s\S] 
    or => (?!a|\x08)[\s\S]

除此之外,两者应始终相同。

答案 4 :(得分:0)

格式[^xy](?:(?!x|y).)不同的情况是x是零宽度断言而不是实际字符,如:

鉴于此示例文本:ab-yz

正则表达式:[^\by]示例:http://www.rubular.com/r/ERKrqyeAs9

返回:

[0] => a
[1] => b
[2] => -
[3] => z

尽管

正则表达式:(?:(?!\b|y).)示例:http://www.rubular.com/r/V5RdyQEQo5

返回:

[0] => b
[1] => z

其他非等效表达式,主要集中在这样一个事实:相同的语法在字符类内部或外部有不同的含义:

  • [^^y]产生a,b, - ,z不等于(?:(?!^|y).)产生b, - ,z
  • [^.y]产生a,b, - ,z不等于(?:(?!.|y).)不产生任何东西

或者你可以在Perl中的unicode nugget中尝试这个:http://ideone.com/2xMfkQ

print "\ncapture\n";
@m = ("ss" =~ m/^(?:(?!\xDF|y).)+$/ui ); 
print for @m;

print "\nclass\n";
@m = ("ss" =~ m/^[^\xDFy]+$/ui) ; 
print for @m;

收率:

capture

class
1