正则表达式 - 匹配一个字符串,但捕获另一个字符串(.NET)

时间:2016-03-09 08:58:41

标签: .net regex

给出一个字符串:

12345XXX3256 | 221456000 | 352456345 | 221324567 | 221654000 |

如果该行包含\ | 221。{3} 000后跟\ | 221。{3}(?!000),即数据组221,其中三个零作为最后一位,后跟数据组,我想匹配221没有三个零作为最后一位数。 (管道符号|分隔数据组。)我可以轻松地使用以下正则表达式。

^.+\|221.{3}000.*\|221.{3}(?!000)

但是,我要捕获的是所有出现的数据组221,其中有三个零作为最后一位(下面显示为粗体)。

组[0]:| 221456000

组[1]:| 221654000

无法弄清楚如何匹配一件事并捕捉另一件事的多次出现。

2 个答案:

答案 0 :(得分:1)

var matches = Regex.Matches(s, @"(?:(\|221...000).*?)+\|221...(?!000)...(?:(\|221...000).*?)*");

,其中

  • (?:(\|221...000).*?)+将匹配并单独捕获|221...000 221... 之前的所有000数据组,至少需要一个此类数据组
  • \|221...(?!000)...将匹配但不会捕获221... 000 数据组
  • (?:(\|221...000).*?)*将匹配并单独捕获|221...000 221...
  • 之后的所有000个数据组

更新:上述正则表达式将|221...000 221... 之前的所有000次出现捕获到一个组中,并且所有{{ {1}}将其继承到另一个。如果你想将它们捕获到一个组中,我建议使用一个命名组:

|221...000

答案 1 :(得分:0)

我认为最简单的方法是匹配符合您要求的线路,然后使用其他正则表达式(或其他技术)来获得所需的输出。它比单独使用正则表达式更有效。

但是,如果您只想使用正则表达式,请尝试以下方法:

(?=(^.*?221\d{3}000.*?221\d{3}[1-9]{3}.+))^\w+|(?<=\G)(221.{3}000)|(?<=\G)\w+|(?<=\G)\|
  • (?=(^.*?221\d{3}000.*?221\d{3}[1-9]{3}.+)) - 积极向前看 你的正则表达式
  • ^\w+ - 包含单词字符的行的开头,
  • | - 或
  • (?<=\G)(221.{3}000) - 前一场比赛的正面观察, 然后是221.{3}000部分捕获组
  • | - 或
  • (?<=\G)\w+ - 前一场比赛的正面观察,后跟任何单词 人物
  • | - 或
  • (?<=\G)\| - 前一场比赛的正面观察, 然后是逃脱逻辑&#34; OR&#34;字符

DEMO1
DEMO2

它会根据您的要求匹配不同的线条元素,但它也会匹配第2组中的(221\d{3}000)部分。因此,如果您想从给定的行中获取所有(221\d{3}000),则需要使用捕获第2组的ale匹配,并比较第1组中捕获的整条线。

无论线路有多长,它都应匹配所有(221\d{3}000)。 但是,这里不可能通过一个组进行直接多重匹配