高级正则表达式-捕获整个组的复杂语句在替换

本文关键字:复杂 语句 替换 正则表达式 高级 | 更新日期: 2023-09-27 18:07:23

我正在做一个项目,我需要解析相关数据…我使用的工具是完全基于命令的,并返回所有类型的东西,所以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->替换,然后用所选组替换整个数据(在听到'Class'组),但它只匹配最后一部分,…内括号,而不是全部。例如,在上面的行中,它将返回"MC"而不是其中的三个,我也试图用('w{2}'s+|'w{2}'s+'w{2}'s+|'w{2}'s+'w{2}'s+'w{2}'s+)替换('w{2}'s+)+),但它也不起作用。

有人能帮我解决这件事吗?谢谢你。

高级正则表达式-捕获整个组的复杂语句在替换

Capture Groups

让我们后退一点。首先,我们需要了解什么是捕获组。括号内的所有内容都将是捕获组。因此,例如,字符串89的正则表达式('d)('d)将捕获第一组中的8和第二组中的9。假设第二个数字是可选的,所以是('d)('d?)。现在,如果您尝试匹配8,那么第一组将是8,而第二组将只是一个空字符串。通过这种方式,我们可以匹配所有组,即使有些组"缺失"。

Non-Capture组

你的正则表达式似乎有大量不必要的捕获组。如果你不需要,就不要用括号。例如,对于(/)?,您可以简单地删除括号。如果你想匹配字符串"123"十倍?你可能会做类似(123){10}的东西。但是,嘿,这是另一个不必要的捕获组!可以使用(?:)代替()创建非捕获组。这样,您将不会捕获括号内的任何内容,但您将有效地使用括号来方便。

你Regex

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

.*/?('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 . regulareexpressions中有这个方便的正则表达式类。你可以这样使用它:
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来测试这类东西

设置为不贪:

.*?((/)?(?<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}