RegExp 仅匹配捕获组中的前两个条目(无论它们是什么)

RegExp matching only the first two entries within a capture group (whatever they happen to be)

我目前正在处理 Adob​​e inDesign 脚本,其中一部分是查找测量并将它们分开的功能。我有一组正则表达式 运行 首先使用 inDesign 的 findGrep() (这里不是很相关),然后使用基本的 javascript exec() (因为我需要做一些事情与捕获组)。

现在,我知道这两个正则表达式引擎之间存在差异,所以我一直在研究更有限的 JS 引擎的功能(我认为 inDesign 的脚本语言基于 ECMAscript v3),但我最近遇到了一个我似乎无法弄清楚的问题。

这是我目前正在测试的正则表达式(我将各行打散以使其更易于阅读 –

  ((?:one|two|three|four|five|six|seven|eight|nine|ten|\d{4,}|\d{1,3}(?:,\d{3})*)(?:\.\d+)?)
  (?=-|‑|\s|°|º|˚|∙|⁰)
  (?:[-\s](thousand|million|billion|trillion))?
  (?:[-\s](cubic|cu\.?|square|sq\.?))?

这是我测试它的示例文本。

23 sq metres
45-square-metres
16-cubic metres
96 cu metres
409 cu. metres
12 sq metres
24 sq. metres

现在,当我 运行 使用 inDesign 的 findGrep() 正则表达式时,它按预期工作。然而,当我 运行 它使用 exec() 时,它做了一些奇怪的事情。它会很好地匹配数字和乘数,但只有“cubic”和“cu”匹配,“square”和“sq”文本将被忽略。

更令人费解的是,如果我在正则表达式捕获组中颠倒这些条目的顺序(所以它是 (?:[-\s](square|sq\.?|cubic|cu\.?))?),那么它只匹配“square”和“sq”而不匹配“cubic” " 和 "cu"。

我是不是漏掉了一些很明显的东西?我是 javascript 新手,但多年来我一直在使用 xslt 中的正则表达式。

str = `23 sq metres
45-square-metres
16-cubic metres
96 cu metres
409 cu. metres
12 sq metres
24 sq. metres
`;
  patt = /((?:one|two|three|four|five|six|seven|eight|nine|ten|\d{4,}|\d{1,3}(?:,\d{3})*)(?:\.\d+)?)(?=-|‑|\s|°|º|˚|∙|⁰)(?:[-\s](thousand|million|billion|trillion))?(?:[-\s](cubic|cu\.?|square|sq\.?))?/gm;
  while (res = patt.exec(str)) console.log(res);

编辑:

所以,这是我现在正在尝试 运行 的代码。

  str = `23 sq metres
    45-square-metres
    16-cubic metres
    96 cu metres
    409 cu. metres
    12 sq metres
    24 sq. metres
    `;
 var re = '(one|two|three|four|five|six|seven|eight|nine|ten|(?:[0-9]|,|\.)+)(?:(\s?(?:-|–)\s?)(one|two|three|four|five|six|seven|eight|nine|ten|(?:[0-9]|,|\.)+))?(?:[-\s](thousand|million|billion|trillion))?(?:[-\s](cubic|cu\.?|square|sq\.?))?'; 
    
patt = new RegExp(re);

while (res = patt.exec(str)) console.log(res);

如果我尝试在我的机器上 运行 使用 inDesign 脚本,它找不到任何带有“square”或“sq”的东西,当我在代码中 运行片段视图在这里它只是冻结了。我猜这与将正则表达式存储为字符串有关,是吗?

我不确定我是否理解正确。如果您希望您的第二个代码以与您的第一个代码大致相同的方式工作,您可能只需要在 RegeExp 构造函数中添加 "gm"

var patt = new RegExp(re, "gm");

str = `23 sq metres
    45-square-metres
    16-cubic metres
    96 cu metres
    409 cu. metres
    12 sq metres
    24 sq. metres
    `;
var re = '(one|two|three|four|five|six|seven|eight|nine|ten|(?:[0-9]|,|\.)+)(?:(\s?(?:-|–)\s?)(one|two|three|four|five|six|seven|eight|nine|ten|(?:[0-9]|,|\.)+))?(?:[-\s](thousand|million|billion|trillion))?(?:[-\s](cubic|cu\.?|square|sq\.?))?'; 
    
var patt = new RegExp(re, "gm");

while (res = patt.exec(str)) console.log(res[5]);

它给了我这个输出:

sq
square
cubic
cu
cu.
sq
sq.

更新

我已将 (cubic|cu\.?|square|sq\.?) 更改为 (cubic|cu\.|cu|square|sq\.|sq),现在似乎可以在 InDesign 中使用:

str = "23 sq metres\n45-square-metres\n16-cubic metres\n96 cu metres\n409 cu. metres\n12 sq metres\n24 sq. metres";

var re = '(one|two|three|four|five|six|seven|eight|nine|ten|(?:[0-9]|,|\.)+)(?:(\s?(?:-|–)\s?)(one|two|three|four|five|six|seven|eight|nine|ten|(?:[0-9]|,|\.)+))?(?:[-\s](thousand|million|billion|trillion))?(?:[-\s](cubic|cu\.|cu|square|sq\.|sq))?'; 
    
var patt = new RegExp(re, "gm");

var msg = "";

while (res = patt.exec(str)) msg += res[0] + " : " + res[5] + "\n";

alert(msg);

可能 (foo|bar) 中的这些 ? 对于 InDesign 脚本模型来说太多了。