RegEx为单个匹配提供多个匹配是否正常?

时间:2016-05-01 03:20:28

标签: javascript regex

如果问题标题有点令人困惑,我很抱歉,但在这里我将详细阐述我的困惑。

我想使用正则表达式匹配苹果,橙子,芒果,苹果[(可以有任何数字或空)],橙色[(可以有任何数字或空)]。 (注意芒果不会有[])。以下是一些有效的例子:

  1. apple MATCHED
  2. orange MATCHED
  3. apple [] MATCHED
  4. orange [] MATCHED
  5. apple [15] MATCHED
  6. apple [05] NOT MATCHED(因为数字不应该以0开头)
  7. mango [] NOT MATCHED(因为芒果不能有[])
  8. 这是我提出的正则表达式:

    /^(mango|(apple|orange)(\[[1-9][0-9]*\])?)$
    

    此正则表达式有效,但通常会提供多个匹配组。例如apple[15]会给出 1. apple[15] 2. apple[15] 3. [15]

    实际上行为是正常的,因为我有很多()创建了很多组,但我想知道我是否正在使用正确的方法构建这个正则表达式?因为它只为一场比赛提供了太多的结果。

    此外,有什么方法可以优化这个正则表达式?这个正则表达式相当简单,但似乎很复杂。

    谢谢。

2 个答案:

答案 0 :(得分:1)

它匹配这些子组,因为这是()的作用。如果要将项目组合在一起而不将其与输出相匹配,请使用non-capturing groups (?:)。例如:(?:apple|orange)将匹配apple或orange,但不会捕获要输出的组。

如果您想仅在没有子组的情况下捕获整个匹配项,请执行以下操作:

^mango$|^(?:apple|orange)(?:\[(?:[1-9][0-9]*)?\])?$

Regex101

var strArr = [ 'apple',
'orange',
'apple[]',
'orange[]',
'apple[15]',
'apple[05]',
'mango[]',
'mango' ];

var re = /^mango$|^(?:apple|orange)(?:\[(?:[1-9][0-9]*)?\])?$/;

strArr.forEach(function(str) {
  document.body.insertAdjacentHTML('beforeend', str + ' - match? ' + re.test(str) + '<br>');
});

铁路图:

enter image description here

答案 1 :(得分:0)

在正则表达式中,您正在声明(G1 |(G2)(G3))。这就是为什么当你匹配时你得到一个有四个值的数组:

1. apple[15] The whole match
2. apple[15] G1 (mango|(apple|orange)(\[1-9][0-9]*\])?)
3. apple G2 (apple|orange)
4. [15] G3 (\[[1-9][0-9]*\])?

如果您将正则表达式更改为/^(mango)|(apple|orange)(\[[1-9][0-9]*\])?$/,则会得到相同的结果,除非您将mango作为输入参数,否则将不会定义上面的#2。请注意,表达式仍会接受mango[123],但匹配项不会包含该数字。