正则表达式量词

时间:2013-04-24 15:56:55

标签: javascript regex

我认为这对我的regEx来说是一个“毫无疑问”的补充,但当然我被证明是错误的......

如果字符串是符号( - ,$,+,=,(,),{,}),我当前的regEx返回true:

(/^[-$+)(}{]$/).test(token);

我想在regEx,赋值运算符(=)和相等运算符(==)中添加两个符号。如果存在一个带有一个或两个'='的标记,我的直觉引导我做一些事情,以便返回true:

(/^[-$+)(}{]|(=){1,2}$/).test(token);

但是如果实际的令牌是(/^[-$+)(}{]|(=){1,2}$/).test("==="),则返回true。

有人可以解释我的regEx缺点吗?

由于

4 个答案:

答案 0 :(得分:6)

您遇到了一个微妙的运算符优先级问题。

/^[-$+)(}{]|(=){1,2}$/

^$绑定比|更紧密,所以这相当于

/(?:^[\-$+)(}{])|(?:={1,2}$)/

而不是您可能想要的^...$包围|

/^(?:[\-$+)(}{]|={1,2})$/

或简化

/^(?:[\-$+(){}]|==?)$/

/^(?:[\-$+(){}]|==?)$/.test("===") === false;
/^(?:[\-$+(){}]|==?)$/.test("()")  === false;
/^(?:[\-$+(){}]|==?)$/.test("=")   === true;
/^(?:[\-$+(){}]|==?)$/.test("==")  === true;
/^(?:[\-$+(){}]|==?)$/.test("(")   === true;

关于捕获与非捕获括号的关注

我更喜欢(?:...)(...),除非我真的想要捕获内容,因为虽然(?:...)更详细,但它对使用正则表达式的代码的影响较小。

当您不打算捕获内容时使用捕获组的一些问题包括:

  1. 更改现有组的编号,因为JS没有命名组,
  2. 使用比我需要的效果更多的操作符可能会让维护者误以为我是因为某种原因而捕获内容,
  3. 更改远程exec循环的行为, (这主要是像@foo = $str =~ /(foo(bar))/g这样的perlish全局匹配问题 但每隔一段时间你就会看到JS代码做类似的事情)
  4. 更改
    newStr = oldStr.replace(
        regexDefinedEarlier,
        function (var_args) {
          return [].slice.call(arguments, 1, arguments.length - 2).join('');
        });
    
  5. 等其他地方定义的(可能的可变参数)替换函数的行为

答案 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。