匹配正则表达式中的重复子串

时间:2009-05-29 21:11:54

标签: regex

正则表达式是否可以根据同一个正则表达式的其他部分进行匹配?

例如,无论字符是什么,我如何匹配以3个字符的相同序列开头和结尾的行?

匹配

abcabc
xyz abc xyz

不匹配:

abc123

未定义:(可以匹配或不匹配,以最简单的方式)

ababa
a

理想情况下,我喜欢perl正则表达式的东西。如果那是不可能的,我有兴趣知道是否有可以做的任何风味。

4 个答案:

答案 0 :(得分:27)

使用捕获组和反向引用。

/^(.{3}).*\1$/

\1引用第一个捕获组内容(()的内容)匹配的内容。大多数语言的正则表达式允许这样的东西。

答案 1 :(得分:16)

您需要backreferences。我们的想法是在第一位使用捕获组,然后在尝试匹配最后一位时再参考它。这是一个匹配一对HTML开始和结束标记的示例(来自前面给出的链接):

<([A-Z][A-Z0-9]*)\b[^>]*>.*?</\1>
     

此正则表达式只包含一对括号,它将[A-Z][A-Z0-9]*匹配的字符串捕获到第一个反向引用中。此反向引用将与\1(反斜杠1)一起重用。之前的/只是我们尝试匹配的结束HTML标记中的正斜杠。

将此应用于您的案例:

/^(.{3}).*\1$/

(是的,这是Brian Carper发布的正则表达式。没有那么多方法可以做到这一点。)

后人的详细解释(如果它在你之下,请不要被侮辱):

  • ^匹配该行的开头。
  • (.{3})抓取任意类型的三个字符并将其保存在一个组中供以后参考。
  • .*尽可能匹配任何内容。 (你不在乎中间的是什么。)
  • \1匹配在步骤2中捕获的组。
  • $匹配该行的结尾。

答案 2 :(得分:3)

对于开头和结尾的相同字符:

/^(.{3}).*\1$/

这是backreference

答案 3 :(得分:2)

这有效:

my $test = 'abcabc';
print $test =~ m/^([a-z]{3}).*(\1)$/;

要匹配开头和结尾,您应添加^$个锚点。