正则表达式:使用量词捕获多个组

时间:2012-08-14 19:45:08

标签: javascript regex

请考虑以下代码:

<!DOCTYPE html>
<html>
<body>
<script type="text/javascript">

var str = '<12> rnbqkb-r Rnbq-b-r ';

var pat1 = new RegExp('^\\<12\\> ([rnbqkpRNBQKP-]{8}) ([rnbqkpRNBQKP-]{8})');
var pat2 = new RegExp('^\\<12\\> ([rnbqkp RNBQKP-]{8}){2}');
var pat3 = new RegExp('^\\<12\\> ([rnbqkp RNBQKP-]{8}){2}?');

document.write(str.match(pat1));
document.write('<br />');
document.write(str.match(pat2));
document.write('<br />');
document.write(str.match(pat3));

</script>
</body>
</html>

产生

<12> rnbqkb-r Rnbq-b-r,rnbqkb-r,Rnbq-b-r
<12> rnbqkb-r Rnbq-b-, Rnbq-b-
<12> rnbqkb-r Rnbq-b-, Rnbq-b-

作为输出。

为什么模式pat2pat3都没有捕获第一组rnbqkb-r?我想捕获所有组,而不必像模式pat1那样明确地重复它们。

2 个答案:

答案 0 :(得分:6)

  

为什么模式pat2和pat3都没有捕获第一组rnbqkb-r?

因为您的正则结构pat2pat3不允许每个8个字符序列的末尾有空格。

  

我想捕获所有组,而不必像模式pat1那样明确地重复它们。

你做不到。

当正则表达式只包含一个组时,无法(在JavaScript中)捕获两个组。

通过括号定义组。您的匹配结果将包含与正则表达式中的括号对一样多的组(除(?:...)之类的修改后的括号外,这些括号不会计入匹配组)。想要在匹配结果中进行两次单独的小组赛吗?在正则表达式中定义两个单独的组。

如果一个群组可以多次匹配,则群组的值将是 last 匹配的任何值。该组的所有先前匹配事件将被其上一次匹配覆盖。

尝试

var pat1 = /^<12> ((?:[rnbqkp-]{8} ?)*)/i,
    match = str.match(pat1);

if (match) {
  match[1].split(/\s+/);  // ["rnbqkb-r", "Rnbq-b-r", ""]
}

注意:

  • 如果您不想要最后一个空数组值,请事先修剪str
  • 通常,更喜欢正则表达式文字符号(/expression/)。仅对从动态值生成的表达式使用new RegExp()
  • <>并不特别,您无需逃避它们。

答案 1 :(得分:2)

再次数(8比9)。 pat2pat3错过了两个部分之间的空间。

更新:此外,我认为使用match尝试实现的目标并非如此。请参阅How can I match multiple occurrences with a regex in JavaScript similar to PHP's preg_match_all()?并使用exec