如何捕获群组

时间:2019-11-12 08:51:10

标签: c# regex

在C#和NET正则表达式引擎中,我有一条像这样的输入线,它以\n终止

1ROSS/SVETA/JAMIE MRS T02XT 2WHITE/VIKA MS 3GREEN/ANDYMR

我必须获得

第一次捕获

 1. num=1
 2. surname=ROSS
 3. name=SVETA
 4. name=JAMIE 
 5. title=MRS 
 6. other=T02XT

第二次捕获

1. num=2
2. surname=WHITE
3. name=VIKA 
4. title=MS

第三次捕获

1. num=3
2. surname=GREEN
3. name=ANDY
4. title=MR

第一组有两个名称,第三组的ANDY和MR中没有空格。我无法解决这个问题。我开始使用

(^\d|\s\d)

检测组并起作用,但是在我不知道如何捕获直到每个组的末尾并将内部数据分成子组之后。

1 个答案:

答案 0 :(得分:0)

如果标题值设置为MRMRSMS,则可以使用

\b(?<num>\d)(?<surname>\p{L}+)(?:/(?<name>\p{L}+?))+(?:\s*(?<title>M(?:RS?|S)))?\b\s*(?<other>.*?)(?=\b\d\p{L}+/\p{L}|$)

请参见regex demo

详细信息

  • \b-单词边界
  • (?<num>\d)-组“ num”:一个数字(如果可以多于1,请替换为\d+
  • (?<surname>\p{L}+)-组“姓”:1个以上字母
  • (?:/(?<name>\p{L}+?))+-/的一个或多个序列,后跟“姓”组:1个以上字母,尽可能少
  • (?:\s*(?<title>M(?:RS?|S)))?-的可选序列
    • \s*-超过0个空格
    • (?<title>M(?:RS?|S))-组“标题”:M后跟R和可选的S或后跟S
  • \b-单词边界
  • \s*-超过0个空格
  • (?<other>.*?)-将“其他”分组:0个或多个字符,并且尽可能少
  • (?=\b\d\p{L}+/\p{L}|$)-直到首次出现的初始模式(单词边界,数字,1 +个字母,/和一个字母)或字符串的结尾。

C# demo

var text = "1ROSS/SVETA/JAMIE MRS T02XT 2WHITE/VIKA MS 3GREEN/ANDYMR";
var pattern = @"\b(?<num>\d)(?<surname>\p{L}+)(?:/(?<name>\p{L}+?))+(?:\s*(?<title>M(?:RS?|S)))?\b\s*(?<other>.*?)(?=\b\d\p{L}+/\p{L}|$)";
var result = Regex.Matches(text, pattern);
foreach (Match m in result) {
    Console.WriteLine("Num: {0}", m.Groups["num"].Value);
    Console.WriteLine("Surname: {0}", m.Groups["surname"].Value);
    Console.WriteLine("Names: {0}", string.Join(", ", m.Groups["name"].Captures.Cast<Capture>().Select(x => x.Value)));
    Console.WriteLine("Title: {0}", m.Groups["title"].Value);
    Console.WriteLine("Other: {0}", m.Groups["other"].Value);
    Console.WriteLine("===== NEXT MATCH ======");
}

输出:

Num: 1
Surname: ROSS
Names: SVETA, JAMIE
Title: MRS
Other: T02XT 
===== NEXT MATCH ======
Num: 2
Surname: WHITE
Names: VIKA
Title: MS
Other: 
===== NEXT MATCH ======
Num: 3
Surname: GREEN
Names: ANDY
Title: MR
Other: 
===== NEXT MATCH ======