【问题标题】:How to use combined capturing groups in RegEx with string.prototype.matchAll?如何将 RegEx 中的组合捕获组与 string.prototype.matchAll 结合使用?
【发布时间】:2021-06-14 06:45:44
【问题描述】:

我尝试使用以下 RegEx 在我的 textInput(字符串)中捕获一些模式:

let idPatterns = /\[id="(.*?)\"]|\[id="(.*?)"]|\[id="(.*?)"]/gim;

对我来说重要的部分是“id”,包括:(.*?)

要提取 id,我使用以下内容:

patternsArray = [...textInput.matchAll(idPatterns)];

我对以下文本的结果是:

文本 [id=“B0076VLVXG”] 文本

数组:

0: "undefined"

但是当我将 idPatterns 变量减少到

let idPatterns = /\[asin="(.*?)"]/gim;

我得到"B0076VLVXG" 作为结果(根据需要)。所以总而言之,我的 idPatterns 的串联似乎不准确,但可以分别使用它们中的每一个。如何正确组合 RegEx 中的三组模式?感谢您的帮助。

function getIdsCombinedRegEx(textInput) {
 
  const idPatterns = /\[id="(.*?)\"]|\[id="(.*?)"]|\[id="(.*?)"]/gim;

  const idPatternsCollection = [...textInput.matchAll(idPatterns)];

  return idPatternsCollection;
}

function getIdsSingleRegEx(textInput) {
 
  const idPatterns = /\[id="(.*?)"]/gim;

  const idPatternsCollection = [...textInput.matchAll(idPatterns)];

  return idPatternsCollection;
}

let textInput = '[id="B07Q45WX5D"] Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. [id="B08CQTNK8S"]';

console.log(getIdsCombinedRegEx(textInput));

console.log(getIdsSingleRegEx(textInput));

【问题讨论】:

  • 我无法重现您的问题,我收到了[ [ "[id="B0076VLVXG"]", undefined, "B0076VLVXG", undefined ] ](在 Windows 10 上使用 Firefox 86)
  • 您确实意识到与组合正则表达式的第一部分匹配将在第 1 组中,与第 2 组中的第二部分匹配,在第 3 组中匹配第三部分,对吧?
  • 您可以将您的正则表达式更改为\[id(?:=|=)("|"|")(.*?)\1],那么比赛将始终在第 2 组中。regex101.com/r/hawfs5/1
  • 在合并单独的正则表达式之前,我得到了一个类似[0: "B0076VLVXG", 1: "B08CQTNK8S", ...] 的数组,其中包含使用 matchAll() 后收集的所有相关 ID。将所有正则表达式合并为一个后,结果显示[0: undefined]。这就是我的困惑的来源。我也添加了一个代码 sn-p。
  • 你的正则表达式确实比我的聪明。我现在可以通过以下方式获取 ID:idPatternsCollection.forEach( (asin, idx, arr) => {arr[idx] = arr[idx][2]}); 谢谢!

标签: javascript regex match


【解决方案1】:

您的正则表达式应该按原样工作,返回第 2 组中的匹配项(因为它被替换的第二个分支中的组捕获:

const idPatterns = /\[id="(.*?)\"]|\[id="(.*?)"]|\[id="(.*?)"]/gim;

const textInput = 'text [id="B0076VLVXG"] text'; 

const patternsArray = [...textInput.matchAll(idPatterns)];

console.log(patternsArray);

由于每次交替都会返回不同组中的匹配项,因此将正则表达式重写为常量捕获组可能更容易。例如:

\[id(?:=|=)("|"|")(.*?)\1]

这寻找:

  • 字符[id
  • ==
  • """ 之一(在第 1 组中捕获)
  • 最少字符数(在第 2 组中捕获)
  • 与第 1 组中捕获的内容相匹配(引用部分)
  • 结束]

regex101 上的正则表达式演示

对于您的扩展数据:

const textInput = '[id="B07Q45WX5D"] Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. [id="B08CQTNK8S"]';

const idPatterns = /\[id(?:=|=)("|"|")(.*?)\1]/gim;

const idPatternsCollection = [...textInput.matchAll(idPatterns)];

// just get group 2
const idValues = idPatternsCollection.map(m => m[2]);

console.log(idValues);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-07
    • 2011-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多