6

考虑以下代码:

<!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-

作为输出。

为什么既没有模式pat2也没有pat3捕获第一组rnbqkb-r?我想捕获所有组,而不必像在 pattern 中那样明确地重复它们pat1

4

2 回答 2

8

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

pat2因为您的正则表达式和pat3不允许的每个 8 字符序列的末尾都有空格。

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

你不能。

当您的正则表达式仅包含一个组时,(在 JavaScript 中)不可能捕获两个组。

组通过括号定义。您的匹配结果将包含与您的正则表达式中的括号对一样多的组(除了(?:...)不计入匹配组的修改括号)。想要在您的比赛结果中进行两场单独的小组赛?在您的正则表达式中定义两个单独的组。

如果一个组可以匹配多次,则该组的值将是最后一次匹配的值。该组的所有先前匹配项将被其最后一次匹配项覆盖。

尝试

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()从动态值生成的表达式。
  • <并且>并不特别,您无需逃避它们。
于 2012-08-14T20:02:17.463 回答
2

再数一遍(8 对 9)。pat2并且pat3缺少两个部分之间的空间。

更新:此外,我不认为您试图通过使用match. 请参阅如何使用 JavaScript 中的正则表达式匹配多个匹配项,类似于 PHP 的 preg_match_all()?并使用exec.

于 2012-08-14T19:51:31.213 回答