高级正则表达式 - 在替换

时间:2016-09-17 05:13:51

标签: c# regex

我正在研究一个项目,我需要解析相关数据...我使用的工具是完全基于命令的,并返回所有类型的东西,所以正则表达式方便而不是猜测这行是那个,另一个是这个,...所以我需要解析这个:

  

1 QB 1283 / YR VC MC MO22AUG IFNTHR 2240 2335 100 0 S

取决于条件可能出现在许多形状上,但是,这将有希望地起作用:

.*((/)?(?<Class>(\w{2}\s+)+)(\w{2}\d{2}\w{3})?\s+\w{6}).*

只有一个问题,我只需捕获这部分: YR VC MC并且无法保证总有三个......我尝试了括号分组,以及命名,你可以看到,我不知道如何在C#中捕获一个组,尽管我认为它使用Regex-&gt;替换然后用选定的组替换整个数据(听'Class'组),但它只匹配内括号的最后一部分,而不是整个数据。例如,在上面的行中,它将返回“MC”而不是其中的三个,我还尝试将(\w{2}\s+)+)替换为(\w{2}\s+|\w{2}\s+\w{2}\s+|\w{2}\s+\w{2}\s+\w{2}\s+),但它也没有用。

任何人都可以帮我解决这个问题吗? 谢谢。

2 个答案:

答案 0 :(得分:3)

捕获组

让我们稍微回顾一下。首先,我们需要了解capture groups是什么。括号内的所有内容都将成为捕获组。因此,例如,带有字符串(\d)(\d)的正则表达式89将捕获第一组中的8和第二组中的9。假设您将第二个数字设为可选,那么(\d)(\d?)。现在,如果您尝试仅匹配8,则第一个组将为8,第二个组将只是一个空字符串。通过这种方式,我们可以匹配所有组,即使有些组“缺失”。

非捕获组

您的正则表达式似乎有大量不必要的捕获组。如果您不需要它,请不要使用括号。例如,对于(/)?,您只需删除括号即可。如果你想匹配字符串“123”十次怎么办?你可能会做(123){10}之类的事情。但是,嘿,这是另一个不需要的捕获组!您可以使用(?:)代替()创建非捕获组。这样,你就不会捕捉括号内的任何内容,但是为了方便你将有效地使用括号。

你的正则表达式

从正则表达式中删除所有不必要的捕获组,我们最终得到:

.*/?(\w{2}\s+)+(?:\w{2}\d{2}\w{3})?\s+\w{6}.*.

其中包括捕获组中的空间,所以让我们把它带出来:

.*/?(\w{2})\s+(?:\w{2}\d{2}\w{3})?\s+\w{6}.*.

此时,捕获组(\w{2})仅匹配示例字符串中的MC,因此,让我们执行您所做的操作并将其拆分为三个不同的捕获组。请注意,我们不能执行类似(\w{2}){1,3}(将\w{2}匹配一到三次)的操作,因为这仍然只有一组括号,因此它只有一个捕获组。因此,我们需要将(\w{2})\s+扩展为(\w{2})\s+(\w{2})\s+(\w{2})\s+。这个正则表达式将正确捕获你的三个字符串。

C#中的正则表达式

在C#中,我们在System.Text.RegularExpressions中有这个方便的Regex类。这就是你如何使用它:

string regex = @".*/?(\w{2})\s+(\w{2})\s+(\w{2})\s+(?:\w{2}\d{2}\w{3})?\s+\w{6}.*";
string sample = "1 QB 1283 /YR VC MC MO22AUG IFNTHR 2240 2335 100 0 S";
Match matches = Regex.Match (sample, regex);
string[] stringGroups = matches.Groups
    .Cast<Group> ()
    .Select (el => el.Value)
    .ToArray ();

这里,stringGroups将是一个包含所有捕获组的字符串数组。 stringGroups [0]将是整个匹配(所以在这种情况下,1 QB 1283 /YR VC MC MO22AUG IFNTHR 2240 2335 100 0 S),stringGroups [1]将是第一个捕获组(在这种情况下为YR),stringGroups [2]是第二个,和stringGroups [3]第三个。

PS:我强烈建议Debuggex测试这类东西。

答案 1 :(得分:2)

让它不贪婪:

.*?((/)?(?<Class>(\w{2}\s+)+)(\w{2}\d{2}\w{3})?\s+\w{6}).*
  ^

或者从两端移除两个贪婪的点。你不需要它们:

/?(?<Class>(?:\w{2}\s+)+)(?:\w{2}\d{2}\w{3})?\s+\w{6}