如何在RegEx中优先考虑重叠模式?

时间:2018-01-16 21:00:12

标签: c# regex negative-lookahead overlapping-matches

我见过几个类似的问题,即使是我自己发布的一个问题,但这是相当具体的。

在正则表达式中有一个匹配模式。现在说在同一个字符串中有两个匹配模式,可以匹配文本。似乎我的运气总是倾向于匹配错误模式的正则表达式。 (我在C#中使用.Net Regex)

我需要分解两种类型的字符串:

  

01 - 第一个值| 02 - 第二个值|空白 - 忽略

  

A - First ValueblankB - Second ValueC - Third Value

所以我想要的结果是使用一个模式字符串匹配Code to Meaning

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个字符,后跟1到3个字符的空格, 连字符,或来自html的mdash。

  • [Bb]lank[ \-–]{0,3} - >空白跟随0-3个字符的空格,连字符或 来自html的mdash

然后

  • (([A-Z][a-z]+[.,;| ]?)+) - >应匹配任何多个单词,包括 可能的空间。所以第一和价值,第二和价值应该是 匹配。

最初的问题是最终的模式组匹配" Valueblank"在第二个输入字符串中。我想以某种方式优先考虑那个" [Bb] lank"应该作为第一组的一部分匹配,而不是第二组的一部分 我尝试在最后一组中放置一个(?![Bb]lank)否定的预测,但它似乎永远不会起作用。任何帮助将不胜感激。

由于

Jaeden" Sifo Dyas" al' Raec Ruiner

2 个答案:

答案 0 :(得分:1)

以下内容(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

“空白”的所有匹配项检查较低的 OR 大写“B”

((?:[A-Z0-9]{1,4}|[Bb]lank)(?=\h[-–]\h)|[Bb]lank)

第一个捕获组:匹配字母数字第一个值或“空白”第一个值与“ - ”或“ - ”匹配(正向前瞻) OR 一个“空白”第一个值没有第二个匹配组。

(?:\h[-–]\h|\|)?

分隔符“ - ” OR “ - ” OR “|”这将发生零次或一次。

(.*?)

不合理地匹配第二个匹配组。

(?=[Bb]lank|\||[A-Z0-9]{1,4}\h[-–]\h|$)

使用正向前瞻,寻找“空白”“|” OR 字母数字第一个值带“ - ”或“ - ”后 OR 行结束(捕捉行上的最后一项)查找结束位置我们应该抓住

答案 1 :(得分:0)

正则表达式将选择第一个最长匹配,即如果两个模式在相同位置开始匹配并匹配相同数量的字符,则将选择较早的替代字符。

例如,以下(愚蠢的例子)将始终匹配第一个替代优先于第二个替代: (+)|富

在你的情况下,如果你真的想要匹配两个项目,其中一个以数字开头,一个以字母开头,为什么不这样做: ([0-9] + ...)|([A-ZA-Z] ....)

尽早匹配两个替补。