【问题标题】:Regex: Repeated Capturing Groups without Global Flag正则表达式:重复捕获没有全局标志的组
【发布时间】:2014-06-27 09:04:57
【问题描述】:

我正在尝试识别和处理文本中的和弦符号。在这样做的过程中,我最终尝试匹配一组重复模式,但只有最后一个匹配的实例出现在返回的数组中。

"Amaj13#11".match(/([a-g][#|b]?)(?:(maj|m|sus|dim|#|b)?(\d+))*/i)

// Expected
["Amaj13#11", "A", "maj", "13", "#", "11"]

// Actual
["Amaj13#11", "A", "#", "11"]

应该捕获其他术语的组是:(?:(maj|m|sus|dim|#|b)?(\d+))*

据我了解,这是因为没有全局标志不存在,当我添加它时,它会正确提取并匹配正确的部分并返回字符串"Amaj13#11",这让我回到了第一格。

如何使用全局标志并将返回的组件放在一个数组中,或者在没有它的情况下重复一个捕获组?

一些示例输入和所需的输出。

"C#m9#5" // ["C#", "m", "9", "#", "5"]
"Bsus2" // ["B", "sus", "2"]
"Db#11" // ["Db", "#", "11"]
"Fmaj6b2" // ["F", "maj", "6", "b", "2"]

【问题讨论】:

  • 您不能“重用”捕获组:请参阅rexegg.com/regex-capture.html 中的自动生成新的捕获组 部分另外,我相信[#|b] 是指[#b]。您能否添加一些示例输入/要求以找到另一种做您想做的事情的方法?
  • 已更新示例。

标签: javascript regex


【解决方案1】:

这是一个有趣的问题,因为虽然它似乎对 javascript 提出了挑战,但它有一个简单的答案。

我建议的方法是忘记捕获组并尝试拆分。但是Javascript没有lookbehinds(用于指定拆分分隔符),据我所知,它没有像PHP那样拆分字符串并保留分隔符的选项。这导致我们采用两步方法。

第一步:确定我们要拆分的位置。从您所说的来看,听起来我们正在研究一个简单的正则表达式,例如

[A-Gb#]|(?:maj|sus)|\d+

请根据您的需要进行修改。

第二步:在分割点插入一个标记。为此,我们使用替换:

readyToSplit = str.replace(/([A-Gb#]|(?:maj|sus)|\d+)/mg, "$1[SPLIT]");

这给了我们:

A[SPLIT]maj[SPLIT]13[SPLIT]#[SPLIT]11[SPLIT]

第三步:拆分。

result = readyToSplit.split(/\[SPLIT\]/m);

这给了我们:Amaj13#11

您可能需要调整令牌,但这是一般的想法。

【讨论】:

  • @DanPrince 这对你有用吗,还是你还在纠结这个问题?
  • 没有收到这条评论,抱歉。在初步了解重用捕获组之后,我继续并只是实现了一个词法解析器。无论如何,都同样欣赏这种方法。
  • 这对我有用。需要匹配字符串中的多个“id”。我拆分它,然后过滤它,使用正则表达式模式作为过滤的委托。像魅力一样工作。
猜你喜欢
  • 1970-01-01
  • 2017-09-13
  • 2011-03-11
  • 2017-01-07
  • 2019-12-19
  • 1970-01-01
  • 2019-05-02
  • 1970-01-01
  • 2011-10-19
相关资源
最近更新 更多