感谢@cool_me5000帮助我解决这个问题的过于简化的版本:PERL: Using REGEX to match a string without the first token repeated in the string. (ABC, not AAA ABC)
以下是调整后的问题:
我试图使用一个正则表达式来匹配第一个实例,其中ATE后面跟着CAT,在ATE和CAT之间没有另一个ATE。我想和“吃蝙蝠猫”相匹配。请注意,在这个文本字符串中,在第一个ATE/CAT组合之后还有其他实例,它们也可以与ATE/CAT相匹配(特别是注意“靠近字符串末尾的ATE狗猫”)如下所示:
$TEXT = "ATE ATE ATE ATE BAT CAT ATE DOG EGG ATE FOR GIN ATE DOG CAT ATE";我第一次尝试:
@finds1=$TEXT=~m/((ATE).*?(CAT))/;
$result = $finds1[0];
print "result = $result\n";这将打印以下内容:
result = ATE ATE ATE ATE BAT CAT当我想要的只是:
result = ATE BAT CAT请注意,我正在尝试创建一个正则表达式,该表达式可以用于B可以是任何字符串的字符。比如吃狗猫,吃胖得帽子小金猫,吃牦牛客栈老KOC慢跑拥抱得到TAL猫。
接下来,我尝试使用“向前看”和“如果”语句相结合的方法。以下是代码:
@finds1=$TEXT=~m/(ATE(?(?!.*?ATE.*?CAT).*?CAT|Z{100}))/;
$result = $finds1[0];
print "result = $result\n";REGEX的第一部分(ATE )告诉perl查找ATE的出现。一旦找到,perl就会处理条件语句,其中条件语句是在ATE之后没有.?ATE.?CAT实例,如果没有找到,则perl查找.*?CAT,如果找到至少一个,那么它将搜索100个Z实例。(我让Perl继续前进的方式,因为无论是在本文中还是在我试图解析的文本中都没有100个Z)。
这将返回:
result = ATE DOG CAT 我第一次认出了猫之后,我已经考虑过用积极的眼光看。但是,正如我前面提到的,第一个ATE.CAT组合之间没有A的字符数是可变的。据我所知,PERL不能执行可变长度的后置检查。
如果您能提供任何帮助或指导,我们将不胜感激!
提前感谢!
发布于 2012-07-04 01:24:11
关于前面的问题,解决办法是:
my ($first) = $text =~ /(A[^AC]*C)/;我们使用了A|C的否定,这意味着我们需要在这里使用ATE|CAT的否定。
每个人都应该知道的是,(?:(?!STRING).)是(?:STRING),[^CHAR]是CHAR。(?:(?!PAT).)还可以处理一些更复杂的模式,包括上面的模式。
所以我们得到:
my ($first) = $text =~ /(ATE (?:(?!ATE|CAT).)* CAT)/sx;解释:
你不想在“吃”和“猫”之间“吃”或“吃”,所以
+---------------- You don't want CAT or ATE starting here.
|+--------------- You don't want CAT or ATE starting here.
||--+------------ You don't want CAT or ATE starting here.
|| +----------- You don't want CAT or ATE starting here.
|| |+---------- You don't want CAT or ATE starting here.
|| ||
vv vv
ATE??...??CAT所以那会是
/
ATE
(?! CAT|ATE ) .
(?! CAT|ATE ) .
...
(?! CAT|ATE ) .
(?! CAT|ATE ) .
CAT
/x重复使用*处理。
https://stackoverflow.com/questions/11321307
复制相似问题