我认为这对我的regEx来说是一个“毫无疑问”的补充,但当然我被证明是错误的......
如果字符串是符号( - ,$,+,=,(,),{,}),我当前的regEx返回true:
(/^[-$+)(}{]$/).test(token);
我想在regEx,赋值运算符(=)和相等运算符(==)中添加两个符号。如果存在一个带有一个或两个'='的标记,我的直觉引导我做一些事情,以便返回true:
(/^[-$+)(}{]|(=){1,2}$/).test(token);
但是如果实际的令牌是(/^[-$+)(}{]|(=){1,2}$/).test("===")
,则返回true。
有人可以解释我的regEx缺点吗?
由于
答案 0 :(得分:6)
您遇到了一个微妙的运算符优先级问题。
/^[-$+)(}{]|(=){1,2}$/
^
和$
绑定比|
更紧密,所以这相当于
/(?:^[\-$+)(}{])|(?:={1,2}$)/
而不是您可能想要的^...$
包围|
:
/^(?:[\-$+)(}{]|={1,2})$/
或简化
/^(?:[\-$+(){}]|==?)$/
/^(?:[\-$+(){}]|==?)$/.test("===") === false;
/^(?:[\-$+(){}]|==?)$/.test("()") === false;
/^(?:[\-$+(){}]|==?)$/.test("=") === true;
/^(?:[\-$+(){}]|==?)$/.test("==") === true;
/^(?:[\-$+(){}]|==?)$/.test("(") === true;
我更喜欢(?:...)
到(...)
,除非我真的想要捕获内容,因为虽然(?:...)
更详细,但它对使用正则表达式的代码的影响较小。
当您不打算捕获内容时使用捕获组的一些问题包括:
exec
循环的行为,
(这主要是像@foo = $str =~ /(foo(bar))/g
这样的perlish全局匹配问题
但每隔一段时间你就会看到JS代码做类似的事情)newStr = oldStr.replace( regexDefinedEarlier, function (var_args) { return [].slice.call(arguments, 1, arguments.length - 2).join(''); });
答案 1 :(得分:4)
由于运算符优先级,或分支包括开始(^
)和结束($
)零宽度匹配。要捕获=或==,您必须使用:
(/^([-$+)(}{]|={1,2})$/).test(token);
答案 2 :(得分:4)
使用此正则表达式:
(/^(?:[-$+)(}{]|={1,2})$/).test(token);
如果您使用锚点^
(开始输入)或$
(结束输入)之前和之后在管道(正则表达式的OR)之后,您必须将|
的LHS和RHS括在括号中以对其进行分组,以便^
或$
适用于括号内的整个正则表达式。
答案 3 :(得分:1)
。 。你的正则表达式的问题很简单:“^”(以...开头)位于“管道”的左侧,“$”(以...结尾)位于右侧。它们只适用于正则表达式的那部分,如下所示:
^[-$+)(}{]
OR
(=){1,2}$
。 。所以,你说"_starts with one of these chars_ or _ends with one or two equal signs_"
,得到它了吗?
。 。你想要的是放一个组,以便“交替”(管道)仅适用于其内容,如下所示:
^([-$+)(}{]|={1,2})$
。 。现在你说:"the text is made of either of _this list of chars_ or _one or two equal signs_"
。
。 Amplexos。