在Regex中,如何将重复组的一部分与之前重复的部分匹配?

时间:2017-09-01 02:32:40

标签: regex regex-group

假设我有一个数据存储或归档系统,我接受一些格式(遗留原因,而不是我自己的设计)

例如,我需要接受

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中这样做?

2 个答案:

答案 0 :(得分:1)

您可以在第一次出现时捕获分隔符,然后再引用它:

[a-z1-9]{4}([.:|])(?:[a-z1-9]{4}\1){2}[a-z1-9]{4}  

请参阅正则表达式demo

  • [a-z1-9]{4}匹配长度为四个字;
  • ([.:|])匹配并捕获分隔符;
  • (?:[a-z1-9]{4}\1){2}捕获第二个和第三个模式,分隔符称为上面捕获的分隔符;
  • [a-z1-9]{4}匹配最后一个字;

答案 1 :(得分:1)

您的正则表达式可能是\w+([.|-])\w+\1\d+\1\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+\1\d+\1\d+' repeat.txt
abcd.efgh.1234.4567
abcd-efgh-1234-4567
abcd|efgh|1234|4567

或者,更通用:

$ grep -P '\w+(\W)\w+(\1\w+)+' repeat.txt
abcd.efgh.1234.4567
abcd-efgh-1234-4567
abcd|efgh|1234|4567

请参阅:example 2。但是,最后一个问题可能是重复组仅捕获最后一次出现。