如何选择将未来的字符串与正则表达式匹配?

Posted

技术标签:

【中文标题】如何选择将未来的字符串与正则表达式匹配?【英文标题】:How do I optionally match future strings with regex? 【发布时间】:2020-09-04 18:37:41 【问题描述】:

我有一个正则表达式,如果我明确匹配字符串的不同部分,我可以匹配它。但我需要字符串的某些部分是可选的。字符串的某些部分是递归的,可以重复:

这是一个字符串示例:[P1]<CX1>=AA1==B-1|R1|[P1]<CX2>-AB1-B2

让我稍微分解一下那根弦的解剖结构。它由以下部分组成:

    [Something] <something> (#|%|=|-|\+)+[A-Z]*[0-9]* -- 该模式可以以不同的排列方式重复(例如,=A1-B2%2##Z 是该模式的三个重复)。 \| 是分隔符 [A-Z]+[0-9]+ \| 另一个分隔符 在此处重复步骤 1-3

第 4 步及以后的步骤作为一个整体是可选的。因此,如果存在步骤 4,那么所有步骤(包括重复步骤 1-3)都必须存在。

我有以下问题:

    匹配步骤 3 中的可选重复排列 匹配从第 4 步开始的所有内容,因为它是可选的

所以所有这些都是有效的,我想要一个正则表达式来捕获步骤 1、2、3(每个排列)和 5 中的组:

[P1]<CX1>=A
[P1]<CX1>%A
[P1]<CX1>-99
[P1]<CX1>=A1-1
[P1]<CX1>=A1-1%C
[P1]<CX1>=A1-1%%C
[P1]<CX1>=A1-1%%C|R1|[P2]<CX1>=A1-23
[P1]<CX1>=A1-1%%C|R1|[P1]<CX2>=A1==B12-C

我将不胜感激任何见解和帮助。

提前致谢!

最好的,

PS:如果这很重要,我正在使用 ruby​​ 的正则表达式引擎。

【问题讨论】:

不确定我是否完全理解,但这对您有用吗? Example 有点长,不过试试^(\[[^][]+\])(&lt;[^&lt;&gt;]*&gt;)([#%=+-][A-Z]*[0-9]*(?:[#%=+-][A-Z]*[0-9]*)*)(?:\|[A-Z]+[0-9]+\|(\[[^][]+\])(&lt;[^&lt;&gt;]*&gt;)([#%=+-][A-Z]*[0-9]*(?:[#%=+-][A-Z]*[0-9]*)*))?$regex101.com/r/bVD1cv/1 读者:据报道,@Thefourthbird 反应如此之快是因为他/她使用听写软件。 ehhmmm.....wut? 如果你想要连续匹配,那么组 1、2,3 和可选的组 5 (?:(\[[^\]\[]+\])(&lt;[^&lt;&gt;]*&gt;)([#%=+-][A-Z]*[0-9]*(?:[#%=+-][A-Z]*[0-9]*)*)|\G(?!\A)\|([A-Z]+[0-9]+)\|) regex101.com/r/MIiQo1/1 【参考方案1】:

如果您想匹配第 1、2、3 组和可选的第 5 组,您可以使用 \G 锚点。

如果只有一个字符串,可以以\G开头:

\G(\[[^\]\[]+\])(<[^<>]*>)([#%=+-][A-Z]*[0-9]*(?:[#%=+-][A-Z]*[0-9]*)*)(?:\|([A-Z]+[0-9]+)\|)?

解释

\G 在上一场比赛结束时或开始时(在本例中为开始时)断言位置 (\[[^\]\[]+\])捕获组1,匹配从开始到结束方括号 (&lt;[^&lt;&gt;]*&gt;)捕获第2组,匹配从开始到结束尖括号 ( 捕获第 3 组 [#%=+-][A-Z]*[0-9]* 匹配任何列出的字符和可选的字符 A-Z 和数字 0-9 (?:[#%=+-][A-Z]*[0-9]*)* 可选择重复上一个模式 )关闭群 (?:\|([A-Z]+[0-9]+)\|)? 可选匹配 Capture group 4 在 2 个管道之间

Regex demo

如果匹配项不必位于字符串的开头,您可以使用带有替换的锚点 |\G(?!\A) 断言它不在字符串的开头。

(?:(\[[^\]\[]+\])(<[^<>]*>)([#%=+-][A-Z]*[0-9]*(?:[#%=+-][A-Z]*[0-9]*)*)|\G(?!\A)\|([A-Z]+[0-9]+)\|)

Regex demo

【讨论】:

感谢您的建议。我作为示例给出的字符串旨在作为单独的字符串读取,而不是多行文本块。对于那个很抱歉。您是否可以帮我将\A\z 分隔符添加到正则表达式以确保我们不会解析多行字符串? 第一个例子只会从字符串的开头匹配。在之前的演示中,我添加了一个可选的换行符来显示所有匹配 rubular.com/r/aVbNI6oWhZASSe

以上是关于如何选择将未来的字符串与正则表达式匹配?的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式如何匹配空值?

如何将重叠字符串与正则表达式匹配?

如何修改一个正则表达式的匹配方式

如何将大字符串中的子字符串与正则表达式匹配? [复制]

正则表达式如何在几个汉字词组之间选择

如何与正则表达式匹配PHP中除“-”之外的所有特殊字符?