【问题标题】:Regular expression that matches group as many times as it can find尽可能多地匹配组的正则表达式
【发布时间】:2016-05-09 11:41:34
【问题描述】:

我写了一个正则表达式来匹配一些看起来像这样的标签:

@("hello, world" bold italic font-size="15")

我希望正则表达式匹配这些字符串:['hello, world', 'bold', 'italic', 'font-size="15"']

但是,只有这些字符串匹配:['hello, world', 'font-size="15"']

其他例子:

  1. (成功)@("test") -> ["test"]
  2. (成功)@("test" bold) -> ["test", "bold"]
  3. (失败)@("test" bold size="15") -> ["test", "bold", 'size="15"']

我尝试过使用这个正则表达式:

\@\(\s*"((?:[^"\\]|\\.)*)"(?:\s+([A-Za-z0-9-_]+(?:\="(?:[^"\\]|\\.)*")?)*)\s*\)

分解版本:

\@\(
  \s*
  "((?:[^"\\]|\\.)*)"
  (?:
    \s+
    (
      [A-Za-z0-9-_]+
      (?:
        \=
        "(?:[^"\\]|\\.)*"
      )?
    )
  )*
  \s*
\)

正则表达式正在尝试

  1. 匹配序列的开头 ($(),
  2. 用转义字符匹配字符串,
  3. 匹配一些 (>= 1) 个空格,
  4. (可选,与 (5) 分组)匹配 = 符号,
  5. (可选,与(4)分组)匹配带有转义字符的字符串,
  6. 重复 (3) - (5)
  7. 匹配序列结尾()

但是,这个正则表达式只匹配"hello, world"font-size="15"。我怎样才能让它也匹配bolditalic,即匹配组([A-Za-z0-9-_]+(?:\="(?:[^"\\]|\\.)*")?)多次?

预期结果:['"hello, world"', 'bold', 'italic', 'font-size="15']

附:使用 JavaScript 原生正则表达式

【问题讨论】:

  • 该字符串是独立的,还是您想在更大的文本中匹配它?
  • 在一个较大的文本中,实际上是一个降价。使用String.match 函数匹配组,然后使用另一个函数处理每个案例。
  • 你能提供更多你想要匹配/不匹配的例子吗?您编写的正则表达式看起来非常复杂,但本应是一项简单的任务。
  • @KubaWyrostek 不,我试过了,但没有用。

标签: javascript regex regex-greedy


【解决方案1】:

您需要一个两步解决方案:

示例代码:

var re = /@\((?:\s*(?:"[^"\\]*(?:\\.[^"\\]*)*"|[\w-]+(?:="?[^"\\]*(?:\\.[^"\\]*)*"?)?))+\s*\)/g; 
var re2 = /(?:"([^"\\]*(?:\\.[^"\\]*)*)"|[\w-]+(?:="?[^"\\]*(?:\\.[^"\\]*)*"?)?)/g;
var str = 'Text here @("hello, world" bold italic font-size="15") and here\nText there @("Welcome home" italic font-size="2345") and there';
var res = [];

while ((m = re.exec(str)) !== null) {
    tmp = [];
    while((n = re2.exec(m[0])) !== null) {
      if (n[1]) {
        tmp.push(n[1]);
      } else {
        tmp.push(n[0]);
      }
    }
    res.push(tmp);
}
document.body.innerHTML = "<pre>" + JSON.stringify(res, 0, 4) + "</pre>";

【讨论】:

  • 非常感谢,也感谢有关使用 RegExp.exec 的提示 - 但是,我使用带有回调的 String.replace 并且效果很好!感谢您为调试这么长的 RegExp 所做的努力!
  • 仅供参考:我用"[^"\\]*(?:\\.[^"\\]*)*" 展开"(?:[^"\\]|\\.)*" 以获得更好的性能。一旦我有更多时间,我可能会添加更多细节。
  • 谢谢你,这只是我自己的小项目 - 我正在尝试制作一个填空生成器(markdown -> pdf),所以性能不会是非常重要的因素 - 虽然是的,但有时正则表达式的性能可能非常糟糕 :) 谢谢
猜你喜欢
  • 2015-07-11
  • 2015-10-26
  • 2020-11-18
  • 2019-06-10
  • 1970-01-01
  • 2013-12-06
  • 1970-01-01
  • 1970-01-01
  • 2020-06-24
相关资源
最近更新 更多