正则表达式是否可以根据同一个正则表达式的其他部分进行匹配?
例如,无论字符是什么,我如何匹配以3个字符的相同序列开头和结尾的行?
匹配
abcabc
xyz abc xyz
不匹配:
abc123
未定义:(可以匹配或不匹配,以最简单的方式)
ababa
a
理想情况下,我喜欢perl正则表达式的东西。如果那是不可能的,我有兴趣知道是否有可以做的任何风味。
答案 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 :(得分:2)
这有效:
my $test = 'abcabc';
print $test =~ m/^([a-z]{3}).*(\1)$/;
要匹配开头和结尾,您应添加^
和$
个锚点。