关于Perl中正则表达式基本规则的混淆

时间:2013-03-24 22:44:04

标签: regex perl

我在理解regex的基本规则时遇到很多困难,并希望有人可以用“简单的英语”来帮助解释它们。

$_ = '1: A silly sentence (495,a) *BUT* one which will be useful. (3)';

print "Enter a regular expression: ";
my $pattern = <STDIN>;
chomp($pattern);

if (/$pattern/) {
    print "The text matches the pattern '$pattern'.\n";
    print "\$1 is '$1'\n" if defined $1;
    print "\$2 is '$2'\n" if defined $2;
    print "\$3 is '$3'\n" if defined $3;
    print "\$4 is '$4'\n" if defined $4;
    print "\$5 is '$5'\n" if defined $5;
}

三个测试输出

Enter a regular expression: ([a-z]+)
The text matches the pattern '([a-z]+)'
$1 is 'silly'

Enter a regular expression: (\w+)
The text matches the pattern '(\w+)'
$1 is '1'

Enter a regular expression: ([a-z]+)(.*)([a-z]+)
The text matches the pattern '([a-z]+)(.*)([a-z]+)'
$1 is 'silly'
$2 is " sentence (495,a) *BUT* one which will be usefu'
$3 is 'l'

我的困惑如下

  1. 不是([a-z]+)意味着“小写字母和一个/多个重复”?如果是这样,不应该“拾取”吗?除非它与()关于记忆(即“愚蠢”是5个字母的单词,所以“将”不会被拾取,但“willx”将会发生?)

  2. (\w+)表示“任何单词和一个/多个重复”?如果是这样,为什么数字“1”被选中,因为没有重复但后面有冒号“:”?

  3. ([a-z]+)(.*)([a-z]+)是否意味着“任何小写并重复”,紧接着是“任何内容和0或更多重复”,紧接着是“任何小写并重复”?如果是这样,为什么输出看起来像上面显示的那样?

  4. 我尽可能多地在网上查询,但仍然无法理解它们。任何帮助将不胜感激。谢谢。

2 个答案:

答案 0 :(得分:6)

  1. 不,这意味着“一个或多个不重音的小写拉丁字母”。

    是的,"will"也会匹配,但匹配操作仅返回第一个匹配项,除非您使用/g

    print "$1\n" while /([a-z]+)/g;  # //g in scalar context
       or
    print "$_\n" for /([a-z]+)/g;    # //g in list context
    

    有关如何使用m/PATTERN/的详细信息,请参阅perlop中的/g

  2. 不,它表示“一个或多个单词字符”,因此它确实可以匹配单个字符。

    或许你对1是一个单词char感到惊讶?在ASCII范围内,单词字符为A-Za-z0-9_。在ASCII范围之外发现另外102,661个字符。

  3. 这意味着“一个或多个非重音的小写拉丁字母,后跟除换行符之外的任意数量的字符,后跟一个或多个无重音的小写拉丁字母”。

    如果您问为什么.*匹配如此之多,引擎将始终在当前位置尽可能匹配。这被称为贪婪。

    也许您正在寻找/([a-z]+)([^a-z]+)([a-z]+)/

答案 1 :(得分:0)

  1. 我真的不确定你为什么会这么想。它查看你的句子并找到第一个小写字母并继续匹配它们直到它找不到。 (在你的情况下是一个空格)这场比赛是'愚蠢',它应该是。匹配在此时停止。

  2. \w匹配“单词字符”并包含数字但不包括标点符号,除了“_”“:”不是单词字符,因此您得到“1”而没有别的。

  3. 这是因为(.*)是“贪婪的”(通常你不应该使用它)。你告诉Perl将任何东西和所有东西都匹配到行尾。然后它会回溯给你最后一次检查的匹配,这是你的字符串的最后一个字符。

  4. 编辑:正如@ikegami所指出的那样,\w实际上比我想的要多得多。