具有以下正则表达式:
([a-z])([0-9])\1
它匹配a5a
,有什么办法让它也匹配a5b
,a5c
等等a5d
?
编辑:好的,我知道我可以使用([a-z])([0-9])([a-z])
但我有一个非常长且复杂的正则表达式(匹配sub-sub-sub-...-domains或匹配 IPv4 地址),这将真正受益于上述行为. 这是否可以通过反向引用或其他任何方式实现?
匿名。答案是我需要的,但似乎是错误的。
具有以下正则表达式:
([a-z])([0-9])\1
它匹配a5a
,有什么办法让它也匹配a5b
,a5c
等等a5d
?
编辑:好的,我知道我可以使用([a-z])([0-9])([a-z])
但我有一个非常长且复杂的正则表达式(匹配sub-sub-sub-...-domains或匹配 IPv4 地址),这将真正受益于上述行为. 这是否可以通过反向引用或其他任何方式实现?
匿名。答案是我需要的,但似乎是错误的。
答案不是反向引用
反向引用意味着匹配之前匹配的值。这并不意味着匹配前面的表达式。但是,如果您的语言允许,您可以在编译之前将字符串中的变量替换为表达式。
Tcl:
set exp1 "([a-z])"
regexp "${exp1}([0-9])${exp1}+" $string
Javascript:
var exp1 = '([a-z])';
var regexp = new RegExp(exp1 + '([0-9])' + exp1 + '+');
string.match(regexp);
珀尔:
my $exp1 = '([a-z])';
$string =~ /${exp1}([0-9])${exp1}+/;
如果第二个字母独立于第一个字母,则不需要反向引用,对吗?
([a-z])([0-9])([a-z])+
编辑
如果您只是不想一遍又一遍地重复最后一部分,那么:
([a-z])([0-9])([a-z])
只是去掉'+'。
正则表达式中反向引用的全部意义在于匹配与指示的子表达式相同的内容,因此无法禁用该行为。
为了获得您想要的行为,以便以后能够重用正则表达式的一部分,您可以只定义您希望在单独的字符串中重用的正则表达式部分,并且(取决于您正在使用的语言) 使用字符串插值或连接从片段构建正则表达式。
例如,在 Ruby 中:
>> letter = '([a-z])'
=> "([a-z])"
>> /#{letter}([0-9])#{letter}+/ =~ "a5b"
=> 0
>> /#{letter}([0-9])#{letter}+/ =~ "a51"
=> nil
或者在 JavaScript 中:
var letter = '([a-z])';
var re = new RegExp(letter + '([0-9])' + letter + '+');
"a5b".match(re)
我怀疑您想要类似于 Perl(?PARNO)
构造的东西(它不仅仅是用于递归;)。
/([a-z])([0-9])(?1)+/
将匹配您想要的 - 对第一个捕获组的任何更改都将反映在(?1)
匹配的内容中。
我不听你的问题?
[a-z][0-9][a-z] Exactly 1
[a-z][0-9][a-z]? One or 0
[a-z][0-9][a-z]+ 1 or more
[a-z][0-9][a-z]* 0 or more
反向引用用于从正则表达式的早期检索数据并在以后使用它。它们不是为了解决风格问题。带有反向引用的正则表达式不会像没有反向引用的那样起作用。您可能只需要习惯正则表达式重复且丑陋。
也许试试 Python,它可以很容易地从较小的块构建正则表达式。不清楚是否允许你改变你的环境……你很幸运一开始就有反向引用。