首页 > 解决方案 > 如何捕获组

问题描述

在 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)

检测组并且它可以工作,但是在我不知道如何捕获每个组结束并将内部数据分成子组之后。

标签: c#regex

解决方案


如果标题值设置为MR,MRSMS,您可以使用

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

查看正则表达式演示

细节

  • \b - 单词边界
  • (?<num>\d)\d+- 组“num”:一个数字(如果可以超过 1 ,则替换为)
  • (?<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# 演示

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 ======

推荐阅读