0

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

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

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

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

和:

A - 第一个值空白B - 第二个值C - 第三个值

所以我想要的结果是使用一个模式字符串将代码与含义匹配

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]+[.,;| ]?)+)--> 应该匹配任何多个单词,包括可能的空格。所以 First 和 Value,Second 和 Value 应该匹配。

最初的问题是最终模式组与第二个输入字符串中的“Valueblank”匹配。我想以某种方式优先考虑“[Bb]lank”应该作为第一组的一部分进行匹配,而不是第二组的一部分。
我尝试(?![Bb]lank)在 finalgroup 中放置一个否定的前瞻,但它似乎从来没有奏效。任何帮助,将不胜感激。

谢谢

Jaeden "Sifo Dyas" al'Raec 毁灭者

4

2 回答 2

1

以下如何(regex101.com 示例):

/((?:[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

“空白”的所有匹配项检查小写大写“B”

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

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

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

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

(.*?)

不贪心地匹配第二个匹配组。

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

使用积极的前瞻,寻找“空白”“|” OR字母数字第一个值与“ - ”或“ - ”在OR行尾之后(捕获行中的最后一项)以找到我们应该捕获的结尾

于 2018-01-16T23:57:55.643 回答
0

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

例如,以下(愚蠢的示例)将始终优先匹配第一个替代方案而不是第二个替代方案: (.+)|foo

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

尽早匹配两个替补。

于 2018-01-16T21:29:42.713 回答