【问题标题】:Arbitrary number of capture groups in multiline strings多行字符串中任意数量的捕获组
【发布时间】:2014-08-31 02:13:17
【问题描述】:

我有一个 Markdown 格式的长字符串,它由一个或多个标题的重复部分和多行描述组成,如下所示:

**[Title1](link1) brief description** flag1, flag2
commentary,
occasionally multi-line
---

**[Title2](link2) brief description** flag3, flag4
**[Title3](link3) brief description** flag5, flag6, flag7
commentary
---

...

此顺序偶尔会与其他文本打断,交织在 --- 和下一个标题之间。

我希望使用 JS 的正则表达式对其进行处理,以便在单独的捕获组中捕获标题、链接、描述和评论。理想情况下,从给出的示例中,我想得到类似:

1st match:
    group 1: Title1
    group 2: link1
    group 3: brief description
    group 4: commentary,
             occasionally multi-line

2nd match:
    group 1: Title2
    group 2: link2
    group 3: brief description 2
    group 4: Title3
    group 5: link3
    group 6: brief description 3
    group 7: commentary

 ...

我不会撒谎 - 我的正则表达式技能可能需要一些改进,但是我设法解决了这个问题,将其限制为单个标题(使用类似于 /\*\*\[(.*)\]\((.*)\)\s+(.*)\*\*.*\s+((?:.*\s)*?)?---/g 的正则表达式)。对于未指定数量的它们,我不确定如何将单独的片段收集到简洁的组中,因为无论我尝试什么,我要么得到属于一个项目的标题的单独匹配项,要么第二个和后续的标题被混搭评论。

这可能只使用正则表达式吗?我想避免按项目边界(在这种情况下为**[---)拆分并从那里进一步切碎,因为这似乎不如单个正则表达式匹配优雅。

【问题讨论】:

  • 预期的捕获量是多少?示例表示赞赏。
  • 我不确定 JS 中的 RegEx 单词如何,但在 PHP 中,点 (.) 不会匹配新行。有一个修饰符 (s),像“/match/s”一样使用,它会告诉 .匹配一切。由于您使用的是点,我认为这些不会匹配新行。
  • @pushpraj 在第二个code 块的原始帖子中提供了预期的捕获。也许我应该使用 capture 而不是 group。如果这不是您的意思,请告诉我。
  • @KohjahBreese 是的,但 \s 可以。给出的正则表达式适用于问题仅限于每个项目一个标题的情况。当存在多个时,我不确定如何进行匹配和捕获。
  • 我无法测试这台 ATM,但从这部分开始:**.*\s+ ----- .* 将匹配任何内容,包括空格。如果添加 ?要做到这一点:**.?*\s+ 它将匹配任何(或不匹配)直到 \s。我会建议,如果可能的话,可以使用 [^\s]* 之类的东西。点会导致问题。

标签: javascript regex capture-group


【解决方案1】:

您正在尝试重复捕获组,然后访问所有捕获。不幸的是,这在 JavaScript 正则表达式引擎中不起作用(大多数其他引擎也是如此)。 .NET 引擎确实支持它。

我知道你不想先分手,但这可能是最好的选择。如果您能以某种方式使用 JS 中的 .NET 正则表达式引擎或将您的项目更改为使用 .NET/Powershell,那么您可能可以在纯正则表达式中完成。

参考

Repeating a Capturing Group vs. Capturing a Repeated Group

【讨论】:

  • 我明白了。糟糕的是,它是网络应用程序中的客户端。拆分和处理它是,然后。谢谢!
【解决方案2】:

我想我用一个正则表达式就可以了

var re = /(?:\*\*\[(.*)\]\((.+)\) (.+)\*\* .*\n)(?:([^\*(?:\-\-\)]+))?/g;

我不确定这是您要求的,但它与您的输入和输出相匹配。 你可以play with it here (Regex101 example)

在这里您可以找到使用该正则表达式并显示捕获的组的JSFiddle

当然不是很严格,所以你可以根据自己的需要进行更改。

我希望这是你想要的。

【讨论】:

  • 问题是,对于提供的示例,我希望它只有两个具有可变捕获次数的匹配项,因为这将简化进一步的处理 - 每个匹配项都对应一个项目,这样我就有了我想在使用exec() 的单个 while 循环中实现的一切。从现在开始,我将不得不权衡我的选择,并决定测试匹配以获取捕获计数是否更可取,或者我应该只是拆分事物并从那里破解。谢谢!
  • 好吧,如果只是它的组织方式让您感到困扰,您可以在 while 循环中重新组织自定义数组或对象中的匹配项。但我不完全确定我理解你试图避免的事情;)
  • 只是想尽可能简洁优雅。处理匹配始终是可能的,但如果可以从单个正则表达式获取所有信息,我想避免这种可能性。我现在知道不是。
  • 嗯,信息在那里,但不是你想要的格式;)祝你继续好运!
猜你喜欢
  • 2021-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-24
相关资源
最近更新 更多