Perl非贪婪正则

目录

贪婪与非贪婪的区别

  贪婪的正则是从后向前匹配,非贪婪的是从前向后匹配。最直观的区别就是这个两种正则匹配结果的字符串长度是:贪婪>=非贪婪。
在使用正则工具(grep,sed等)时一定要注意这两种模式的区别。

贪婪的问题

sed可惜只支持贪婪的正则,这就造成处理某些问题时比较麻烦。比如这个问题,去掉下面这句话的HTML标签:
I love <bold>you</bold>, not <bold>her</bold>

用sed我们可能会这样写

echo "I love <bold>you</bold>, not <bold>her</bold>" |sed 's#<bold>\(.*\)</bold>#\1#g'

但是结果却是这样的:

I love you</bold>, not <bold>her
这很显然不是我们想要的结果,出来这个结果的原因正是sed使用了贪婪的正则

当然我们也可以下面这样写解决问题,但是看起来就麻烦一些了

echo "I love <bold>you</bold>, not <bold>her</bold>" |sed 's#<bold>\([A-Za-z]\+\)</bold>#\1#g'
#sed要解决贪婪问题只有提供更精细的正则,但有时这并不容易

使用Perl的非贪婪正则

Perl的默认正则也是贪婪的,但是我们可以使用.*?,.+?等来实现非贪婪的正则
jimila@CDYJY-JINGML:$ echo "I love <bold>you</bold>, not <bold>her</bold>" |perl -we '$_=<>;s#<bold>(.*?)</bold>#$1#g;print $_;'                             
I love you, not her

目录