在 Regex 中,如何将重复组的一部分与前一个重复的部分匹配?
How do you match part of a repeating group to a part from a previous repeat, in Regex?
假设我有一个数据存储或归档系统并且我接受一些格式(遗留原因,不是我自己的设计)
例如,我需要接受
abcd.efgh.1234.4567
abcd-efgh-1234-4567
abcd|efgh|1234|4567
但不是
abcd.efgh-1234|4567
基本上我需要对我使用的分隔符保持一致。我正在尝试构建一个可以检查的正则表达式,但我发现它真的很棘手。我已经探索了正则表达式引用并了解它们如何用于查找像 abc-abc-abc
这样的重复,但在我的情况下,我需要它来允许 abcd
部分不同并且只有 确保我有相同的分隔符
这是我目前得到的结果 (link to Regex101);
(([a-z1-9]){4}([\.:|])){3}(([a-z1-9]){4})
我需要以某种方式给出对那个 ([\.:|])
的反向引用,但我不能把它放在那里,因为它需要自己重复。
在 Regex 中有没有办法做到这一点?
您可以在分隔符第一次出现时捕获它,稍后再反向引用它:
[a-z1-9]{4}([.:|])(?:[a-z1-9]{4}){2}[a-z1-9]{4}
参见正则表达式 demo。
[a-z1-9]{4}
匹配长度为四个字;
([.:|])
匹配并捕获分隔符;
(?:[a-z1-9]{4}){2}
捕获第二个和第三个模式,分隔符参考上面捕获的分隔符;
[a-z1-9]{4}
匹配最后一个词;
您的正则表达式可以是 \w+([.|-])\w+\d+\d+
请参阅:example 1
它对第一个遇到的分隔符(“|”、“.”或“-”)使用反向引用 \1
测试:
$ cat repeat.txt
abcd.efgh.1234.4567
abcd-efgh-1234-4567
abcd|efgh|1234|4567
abcd.efgh-1234|4567
结果:
$ grep -P '\w+([.|-])\w+\d+\d+' repeat.txt
abcd.efgh.1234.4567
abcd-efgh-1234-4567
abcd|efgh|1234|4567
或者,更通用:
$ grep -P '\w+(\W)\w+(\w+)+' repeat.txt
abcd.efgh.1234.4567
abcd-efgh-1234-4567
abcd|efgh|1234|4567
参见:example 2。不过,最后一个的问题可能是重复组仅捕获最后一次出现的事件。
假设我有一个数据存储或归档系统并且我接受一些格式(遗留原因,不是我自己的设计)
例如,我需要接受
abcd.efgh.1234.4567
abcd-efgh-1234-4567
abcd|efgh|1234|4567
但不是
abcd.efgh-1234|4567
基本上我需要对我使用的分隔符保持一致。我正在尝试构建一个可以检查的正则表达式,但我发现它真的很棘手。我已经探索了正则表达式引用并了解它们如何用于查找像 abc-abc-abc
这样的重复,但在我的情况下,我需要它来允许 abcd
部分不同并且只有 确保我有相同的分隔符
这是我目前得到的结果 (link to Regex101);
(([a-z1-9]){4}([\.:|])){3}(([a-z1-9]){4})
我需要以某种方式给出对那个 ([\.:|])
的反向引用,但我不能把它放在那里,因为它需要自己重复。
在 Regex 中有没有办法做到这一点?
您可以在分隔符第一次出现时捕获它,稍后再反向引用它:
[a-z1-9]{4}([.:|])(?:[a-z1-9]{4}){2}[a-z1-9]{4}
参见正则表达式 demo。
[a-z1-9]{4}
匹配长度为四个字;([.:|])
匹配并捕获分隔符;(?:[a-z1-9]{4}){2}
捕获第二个和第三个模式,分隔符参考上面捕获的分隔符;[a-z1-9]{4}
匹配最后一个词;
您的正则表达式可以是 \w+([.|-])\w+\d+\d+
请参阅:example 1
它对第一个遇到的分隔符(“|”、“.”或“-”)使用反向引用 \1
测试:
$ cat repeat.txt
abcd.efgh.1234.4567
abcd-efgh-1234-4567
abcd|efgh|1234|4567
abcd.efgh-1234|4567
结果:
$ grep -P '\w+([.|-])\w+\d+\d+' repeat.txt
abcd.efgh.1234.4567
abcd-efgh-1234-4567
abcd|efgh|1234|4567
或者,更通用:
$ grep -P '\w+(\W)\w+(\w+)+' repeat.txt
abcd.efgh.1234.4567
abcd-efgh-1234-4567
abcd|efgh|1234|4567
参见:example 2。不过,最后一个的问题可能是重复组仅捕获最后一次出现的事件。