正则表达式

除了Perl以外,正则表达式也被应用在许多其他的语言和工具中。Perl的核心正则表达式语法基本上和其他地方别无二致,不过Perl完整的正则表达式功能复杂到令人发指,并且难以理解。我能给的最好的建议就是尽可能避免引入不必要的复杂性。

=~ m//运算符进行正则表达式匹配。在scalar上下文中,=~ m//在成功时返回true,而失败是返回false。

  1. my $string = "Hello world";
  2. if($string =~ m/(\w+)\s+(\w+)/) {
  3. print "success";
  4. }

圆括号表示匹配组,匹配成功以后,匹配组被填入内置变量$1$2$3……:

  1. print $1; # "Hello"
  2. print $2; # "world"

在列表上下文中,=~ m//返回$1$2……组成的列表。

  1. my $string = "colourless green ideas sleep furiously";
  2. my @matches = $string =~ m/(\w+)\s+((\w+)\s+(\w+))\s+(\w+)\s+(\w+)/;
  3. print join ", ", map { "'".$_."'" } @matches;
  4. # prints "'colourless', 'green ideas', 'green', 'ideas', 'sleep', 'furiously'"

=~ s///运算符进行正则表达式替换。

  1. my $string = "Good morning world";
  2. $string =~ s/world/Vietnam/;
  3. print $string; # "Good morning Vietnam"

请注意$string的内容发生了怎样的改变。你必须在=~ s///运算符左边提供一个scalar变量,如果你提供了字面字符串,会返回一个错误。

/g标志表示“全局匹配”(译者注:原文“group match”,应为“global match”更为确切)。

在scalar上下文中,每次=~ m//g调用都会返回下一个匹配项,成功是返回true,而失败时返回false。然后你还是可以通过$1等等来得到匹配的组。例如:

  1. my $string = "a tonne of feathers or a tonne of bricks";
  2. while($string =~ m/(\w+)/g) {
  3. print "'".$1."'\n";
  4. }

在列表上下文中,=~ m//g一次性返回所有匹配的结果。

  1. my @matches = $string =~ m/(\w+)/g;
  2. print join ", ", map { "'".$_."'" } @matches;

每次=~ s///g调用会进行一次全局的查找/替换,并且返回匹配的次数。在这里,我们把所有元音字母用字母“r”替代。

  1. # 先不用/g进行一次替换
  2. $string =~ s/[aeiou]/r/;
  3. print $string; # "r tonne of feathers or a tonne of bricks"
  4. # 再替换一次
  5. $string =~ s/[aeiou]/r/;
  6. print $string; # "r trnne of feathers or a tonne of bricks"
  7. # 用/g全部替换
  8. $string =~ s/[aeiou]/r/g;
  9. print $string, "\n"; # "r trnnr rf frrthrrs rr r trnnr rf brrcks"

/i标志表示查找替换对于大小写不敏感。

/x标志允许正则表达式中包含空白符(例如换行符)和注释。

  1. "Hello world" =~ m/
  2. (\w+) # one or more word characters
  3. [ ] # single literal space, stored inside a character class
  4. world # literal "world"
  5. /x;
  6. # returns true