如何确定 RegEx 中重叠模式的优先级?
How can I Prioritize Overlapping Patterns in RegEx?
我看到过几个类似的问题,甚至有一个是我自己发的,但这个问题很具体。
在正则表达式中有一个匹配模式。现在说在同一个字符串中有两个匹配模式都可以匹配文本。似乎我的运气总是倾向于匹配错误模式的正则表达式。 (我在 C# 中使用 .Net Regex)
我有两种类型的字符串需要分解:
01 - First Value|02 - Second Value|Blank - Ignore
并且:
A - First ValueblankB - Second ValueC - Third Value
所以我想要的结果是用一个模式字符串将代码与含义匹配
Code,Meaning
01,First Value
02,Second Value
Blank,Ignore
A,First Value
blank,
B,Second Value
C,Third Value
我尝试了几种模式,但似乎永远无法完全正确。我能得到的最接近的是:
(([A-Z0-9]{1,4})[ \-–]{1,3}|([Bb]lank)[ \-–]{0,3})(([A-Z][a-z]+[.,;| ]?)+)
我的细分:
[A-Z0-9]{1,4}[ \-–]{1,3}
--> 这匹配代码,大写,或者
长度为 1 - 4 个字符的数字,后跟 space 的 1 到 3 个字符,
来自 html. 的连字符或 mdash
或
[Bb]lank[ \-–]{0,3}
--> 空白后跟 space、连字符或 0-3 个字符
来自 html 的破折号
然后
(([A-Z][a-z]+[.,;| ]?)+)
--> 应该匹配任何多个单词,包括
可能 space。所以第一和价值,第二和价值应该是
匹配。
最初的问题是最终模式组与第二个输入字符串中的 "Valueblank" 相匹配。我想以某种方式优先考虑“[Bb]lank”应该作为第一组的一部分进行匹配,而不是第二组的一部分。
我尝试在 finalgroup 中放置一个 (?![Bb]lank)
negative lookahead,但它似乎从来没有奏效。任何帮助将不胜感激。
谢谢
Jaeden "Sifo Dyas" al'Raec Ruiner
正则表达式将选择第一个最长的匹配项,也就是说,如果两个模式在相同位置开始匹配并匹配相同数量的字符,则会选择较早的替代项。
例如,以下(愚蠢的示例)将始终匹配第一个备选方案而不是第二个备选方案:
(.+)|foo
在你的情况下,如果你真的想匹配两个项目,其中一个以数字开头,一个以字母开头,为什么不这样做:
([0-9]+...)|([A-Za-z]...)
尽早匹配两个候补。
以下 (regex101.com example):
/((?:[A-Z0-9]{1,4}|[Bb]lank)(?=\h[-–]\h)|[Bb]lank)(?:\h[-–]\h|\|)?(.*?)(?=[Bb]lank|\||[A-Z0-9]{1,4}\h[-–]\h|$)/gm
说明
[Bb]lank
"blank" 的所有匹配项检查小写 或 大写 "B"
((?:[A-Z0-9]{1,4}|[Bb]lank)(?=\h[-–]\h)|[Bb]lank)
第一个捕获组:将字母数字第一个值或 "blank" 第一个值与“-”或“-”匹配(正先行)OR "blank" 没有第二个匹配组的第一个值。
(?:\h[-–]\h|\|)?
“-”的分隔符OR“-”OR“|”这将发生零次或一次。
(.*?)
误匹配第2个匹配组
(?=[Bb]lank|\||[A-Z0-9]{1,4}\h[-–]\h|$)
使用积极的前瞻,寻找 "blank" OR "|" OR 字母数字第一个值在 OR 行末尾后带有“-”或“-”(以捕获行中的最后一项)找到我们应该捕获的地方的尽头
我看到过几个类似的问题,甚至有一个是我自己发的,但这个问题很具体。
在正则表达式中有一个匹配模式。现在说在同一个字符串中有两个匹配模式都可以匹配文本。似乎我的运气总是倾向于匹配错误模式的正则表达式。 (我在 C# 中使用 .Net Regex)
我有两种类型的字符串需要分解:
01 - First Value|02 - Second Value|Blank - Ignore
并且:
A - First ValueblankB - Second ValueC - Third Value
所以我想要的结果是用一个模式字符串将代码与含义匹配
Code,Meaning
01,First Value
02,Second Value
Blank,Ignore
A,First Value
blank,
B,Second Value
C,Third Value
我尝试了几种模式,但似乎永远无法完全正确。我能得到的最接近的是:
(([A-Z0-9]{1,4})[ \-–]{1,3}|([Bb]lank)[ \-–]{0,3})(([A-Z][a-z]+[.,;| ]?)+)
我的细分:
[A-Z0-9]{1,4}[ \-–]{1,3}
--> 这匹配代码,大写,或者 长度为 1 - 4 个字符的数字,后跟 space 的 1 到 3 个字符, 来自 html. 的连字符或 mdash
或
[Bb]lank[ \-–]{0,3}
--> 空白后跟 space、连字符或 0-3 个字符 来自 html 的破折号
然后
(([A-Z][a-z]+[.,;| ]?)+)
--> 应该匹配任何多个单词,包括 可能 space。所以第一和价值,第二和价值应该是 匹配。
最初的问题是最终模式组与第二个输入字符串中的 "Valueblank" 相匹配。我想以某种方式优先考虑“[Bb]lank”应该作为第一组的一部分进行匹配,而不是第二组的一部分。
我尝试在 finalgroup 中放置一个 (?![Bb]lank)
negative lookahead,但它似乎从来没有奏效。任何帮助将不胜感激。
谢谢
Jaeden "Sifo Dyas" al'Raec Ruiner
正则表达式将选择第一个最长的匹配项,也就是说,如果两个模式在相同位置开始匹配并匹配相同数量的字符,则会选择较早的替代项。
例如,以下(愚蠢的示例)将始终匹配第一个备选方案而不是第二个备选方案: (.+)|foo
在你的情况下,如果你真的想匹配两个项目,其中一个以数字开头,一个以字母开头,为什么不这样做: ([0-9]+...)|([A-Za-z]...)
尽早匹配两个候补。
以下 (regex101.com example):
/((?:[A-Z0-9]{1,4}|[Bb]lank)(?=\h[-–]\h)|[Bb]lank)(?:\h[-–]\h|\|)?(.*?)(?=[Bb]lank|\||[A-Z0-9]{1,4}\h[-–]\h|$)/gm
说明
[Bb]lank
"blank" 的所有匹配项检查小写 或 大写 "B"
((?:[A-Z0-9]{1,4}|[Bb]lank)(?=\h[-–]\h)|[Bb]lank)
第一个捕获组:将字母数字第一个值或 "blank" 第一个值与“-”或“-”匹配(正先行)OR "blank" 没有第二个匹配组的第一个值。
(?:\h[-–]\h|\|)?
“-”的分隔符OR“-”OR“|”这将发生零次或一次。
(.*?)
误匹配第2个匹配组
(?=[Bb]lank|\||[A-Z0-9]{1,4}\h[-–]\h|$)
使用积极的前瞻,寻找 "blank" OR "|" OR 字母数字第一个值在 OR 行末尾后带有“-”或“-”(以捕获行中的最后一项)找到我们应该捕获的地方的尽头