2010-01-14 89 views
2

具有以下正则表达式:正则表达式反向引用

([a-z])([0-9])\1 

它匹配a5a,有没有什么办法让它也匹配a5ba5ca5d等等?


编辑:好吧,我明白,我可以只使用([a-z])([0-9])([a-z]),但我有一个非常漫长而复杂的正则表达式(匹配子子子-...-域匹配一个IPv4地址)将真正受益于上述行为。这是否有可能通过反向引用或其他方式实现?


Anon. answer正是我需要的,但它似乎是错误的。

回答

2

如果第二个字母与第一个字母无关,那么您不需要返回引用,对吗?

([a-z])([0-9])([a-z])+ 

编辑

如果你只是不想在重复过去的一部分,一遍又一遍,然后:

([a-z])([0-9])([a-z]) 

就收走了 '+'。

+0

谢谢麸,但请检查我的编辑。 – 2010-01-14 02:02:56

+0

不,我想得到你提供的第一个正则表达式的效果'([a-z])([0-9])([a-z])+',但不必一遍又一遍地重复最后一部分。 – 2010-01-14 02:17:02

0

我不遵循你的问题?

[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 
+0

你能检查一下我的编辑吗?谢谢。 – 2010-01-14 02:03:40

2

正则表达式反向引用的整点是相匹配的同样的事情指示的子表达式,所以没有方法来禁用该行为。

为了获得您想要的行为,以后能够重复使用正则表达式的一部分,您可以将正则表达式的部分定义为希望在单独的字符串中重用,以及(取决于您使用的语言'正在处理中)使用字符串插值或串联来从各个部分构建正则表达式。

例如,在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) 
1

我怀疑你想类似于Perl的(?PARNO)结构的东西(它不只是递归)。

/([a-z])([0-9])(?1)+/ 

将匹配你想要什么 - 第一撷取组的任何更改将在(?1)比赛有什么反映。

+0

似乎是我在找的东西,然而你提供的正则表达式给了我RegexBuddy中的错误(在PCRE和Perl模式下)。 – 2010-01-14 02:15:32

+0

适用于我的Perl版本。 – 2010-01-14 02:24:43

+0

正则表达式的'(?1)'部分在Perl模式下给我RegexBuddy中的以下错误:**错误的字符(可能不完整的正则表达式标记或未转义的元字符)**,无论如何。 =) – 2010-01-14 02:47:49

3

答案是不是反向引用

向引用意味着匹配先前匹配的值。这并不意味着与以前的表达相匹配。但是,如果你的语言允许它,你可以在编译之前将字符串中的一个变量替换为你的表达式。

的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); 

的Perl:

my $exp1 = '([a-z])'; 
$string =~ /${exp1}([0-9])${exp1}+/; 
0

反向引用是用于检索来自正则表达式中的早期数据并在以后使用它。他们不是为了解决文体问题。带反向引用的正则表达式不会像没有正则表达式一样运行。你可能只需要习惯regexes是重复和丑陋的。

也许试试Python,这可以很容易地从小块建立正则表达式。不清楚你是否被允许改变你的环境......你很幸运,首先有反向引用。