转自:http://www.yiibai.com/perl/perl_regular_expression.html
正则表达式是一个字符串的字符定义视图的模式或多模式。在Perl的正则表达式的语法是什么,你会发现在其他正则表达式,如sed,grep和awk的支持程序非常相似。
运用正则表达式的基本方法是使用结合的经营模式=〜和!〜。第一个是一个测试操作符,第二是一个赋值操作符。
- 匹配正则表达式 - m//
- 替代正则表达式 - s///
- 直译(拼写)正则表达式 - tr///
在每种情况下斜线作为正则表达式(regex的),你指定的分隔符。如果你喜欢用任何其他分隔符,那么你可以代替使用斜线的位置。
匹配操作符
m//匹配操作符,用来匹配一个正则表达式字符串或语句。例如,要匹配的字符序列“foo”对标量$bar,你可能会使用这样的语句:
if ($bar =~ /foo/)
m//其实与同样功能的q//操作符。你可以使用任何自然匹配的字符作为分隔符表达式的组合,例如,{},m(),和m><都是有效的。
如果分隔符是斜杠,你可以从m//省略 成m,但所有其他的分隔符,你必须使用m前缀。
请注意,整个匹配表达式表现出来。即=〜!或〜匹配操作符左边的表达式,返回true(在标量上下文)如果表达式匹配。因此,语句:
$true = ($foo =~ m/foo/);
将会设置$true的值为1 如果$foo匹配正则表达式, 否则$true为0匹配失败。
匹配在列表上下文中,返回任何分组表达式的内容。例如,从字符串中提取的小时,分钟和秒时,我们可以使用:
my ($hours, $minutes, $seconds) = ($time =~ m/(\d+):(\d+):(\d+)/);
匹配运算符修饰符
匹配的操作符支持其自己的一套修饰符。 /g的修饰符,使全局匹配,/i修饰符将匹配不区分大小写。这里是完整的修饰符列表:
Modifier Description i Makes the match case insensitive m Specifies that if the string has newline or carriage return characters, the ^ and $ operators will now match against a newline boundary, instead of a string boundary o Evaluates the expression only once s Allows use of . to match a newline character x Allows you to use white space in the expression for clarity g Globally finds all matches cg Allows the search to continue even after a global match fails
只匹配一次
还有一个简单的版本匹配操作符 - ?Pattern?操作符。这基本上是等同于m//运算符但它仅匹配一次在字符串之间的每个调用reset。
例如,可以使用此列表内的第一个和最后一个元素:
#!/usr/bin/perl @list = qw/food foosball subeo footnote terfoot canic footbrdige/; foreach (@list) { $first = $1 if ?(foo.*)?; $last = $1 if /(foo.*)/; } print "First: $first, Last: $last\n"; # by www.yiibai.com This will produce following result First: food, Last: footbrdige
替换操作符
替换操作符,s///确实是只是一个扩展,使您可以更换一些新的文本匹配的文本匹配运算符。此运算符基本形式是:
s/PATTERN/REPLACEMENT/;
PATTERN 是我们正在寻找的正则表达式的文本。REPLACEMENT 是一个规范,我们要用来替换找到的文字与文本或正则表达式。
例如,我们可以使用.cat. 替换所有出现的.dog。
$string =~ s/dog/cat/;
另外一个例子:
#/user/bin/perl $string = 'The cat sat on the mat'; $string =~ s/cat/dog/; print "Final Result is $string\n"; This will produce following result The dog sat on the mat
替换操作符修饰符
这里是替代操作符的所有修改的列表:
Modifier Description i Makes the match case insensitive m Specifies that if the string has newline or carriage return characters, the ^ and $ operators will now match against a newline boundary, instead of a string boundary o Evaluates the expression only once s Allows use of . to match a newline character x Allows you to use white space in the expression for clarity g Replaces all occurrences of the found expression with the replacement text e Evaluates the replacement as if it were a Perl statement, and uses its return value as the replacement text
转换
转换相似但不完全相同替换的原则,但不像替换,转换(翻译)不使用正则表达式搜索替换值。转换操作符是:
tr/SEARCHLIST/REPLACEMENTLIST/cds y/SEARCHLIST/REPLACEMENTLIST/cds
翻译替换在SEARCHLIST与在REPLACEMENTLIST相应出现的字符所有字符。例如,使用“The cat sat on the mat.”字符串我们已经在本章中使用:
#/user/bin/perl $string = 'The cat sat on the mat'; $string =~ tr/a/o/; print "$string\n"; This will produce following result The cot sot on the mot.
也可用于标准的Perl范围,允许你指定字符的范围,由字母或数值。要改变字符串的情况下,您可以使用以下语法在位置的uc函数。
$string =~ tr/a-z/A-Z/;
转换操作符
以下是有关操作符的运算符名单
Modifier Description c Complement SEARCHLIST. d Delete found but unreplaced characters. s Squash duplicate replaced characters.
/ D的修饰符删除匹配SEARCHLIST的字符,不具备相应的条目在REPLACEMENTLIST。例如:
#!/usr/bin/perl $string = 'the cat sat on the mat.'; $string =~ tr/a-z/b/d; print "$string\n"; This will produce following result b b b.
最后的修饰符,/s删除被替换的字符的重复序列,因此:
#!/usr/bin/perl $string = 'food'; $string = 'food'; $string =~ tr/a-z/a-z/s; print $string; This will produce following result fod
更复杂的正则表达式
你不只是有固定的字符串匹配。事实上,你可以在任何可以使用更复杂的正则表达式只是匹配。这里有一个快速的小抄:
Character Description . a single character \s a whitespace character (space, tab, newline) \S non-whitespace character # by www.yiibai.com \d a digit (0-9) \D a non-digit \w a word character (a-z, A-Z, 0-9, _) \W a non-word character [aeiou] matches a single character in the given set [^aeiou] matches a single character outside the given set (foo|bar|baz) matches any of the alternatives specified
量词可以用来指定有多少以前的东西,你要匹配,其中“thing”是指一个原义字符,上面列出的元字符,或一组括号中的字符或元字符。
Character Description * zero or more of the previous thing + one or more of the previous thing ? zero or one of the previous thing {3} matches exactly 3 of the previous thing {3,6} matches between 3 and 6 of the previous thing {3,} matches 3 or more of the previous thing
^元字符匹配字符串的开头和 $ metasymbol 匹配字符串的结尾。
这里有一些简单的例子
# nothing in the string (start and end are adjacent) /^$/ # a three digits, each followed by a whitespace # character (eg "3 4 5 ") /(\d\s){3}/ # matches a string in which every # odd-numbered letter is a (eg "abacadaf") /(a.)+/ # string starts with one or more digits /^\d+/ # string that ends with one or more digits /\d+$/
让我们看看另一个例子
#!/usr/bin/perl $string = "Cats go Catatonic\nWhen given Catnip"; ($start) = ($string =~ /\A(.*?) /); @lines = $string =~ /^(.*?) /gm; print "First word: $start\n","Line starts: @lines\n"; This will produce following result First word: Cats Line starts: Cats When
匹配边界
\b匹配任何单词边界,\w类和\W类之间的区别定义。 因为\w一个字的字符,\W相反,这通常是指一个词的终止。 \B断言不是一个单词边界匹配任何位置。例如:
/\bcat\b/ # Matches 'the cat sat' but not 'cat on the mat' /\Bcat\B/ # Matches 'verification' but not 'the cat on the mat' /\bcat\B/ # Matches 'catatonic' but not 'polecat' /\Bcat\b/ # Matches 'polecat' but not 'catatonic'
选择替代品
|字符是一样的标准或按位或在Perl。它指定一个正则表达式或组内的备用匹配。例如,以匹配表达式中的“cat”或“dog”,你可能会使用这个:
if ($string =~ /cat|dog/)
您可以将单个表达式的元素结合在一起,以支持复杂的匹配。寻找两个人的名字,可以实现两个独立的测试,像这样:
if (($string =~ /Martin Brown/) || ($string =~ /Sharon Brown/)) This could be written as follows if ($string =~ /(Martin|Sharon) Brown/)
分组匹配
从一个角度的正则表达式看没有区别,也许前者是稍微更清晰。
$string =~ /(\S+)\s+(\S+)/; and $string =~ /\S+\s+\S+/;
然而,在分组的好处是,它使我们能够从一个正则表达式提取序列。返回一个列表的顺序,在他们出现在原来的分组。例如,在下面的片段中,我们已经从一个字符串取出小时,分钟和秒。
my ($hours, $minutes, $seconds) = ($time =~ m/(\d+):(\d+):(\d+)/);
除了这种直接的方法,也可以在特殊的$x变量,其中x是该组内一些正则表达式匹配组。因此,我们可以重写前面的例子如下:
$time =~ m/(\d+):(\d+):(\d+)/; my ($hours, $minutes, $seconds) = ($1, $2, $3);
当组用于替代表达式,$ x的语法,可以用来替换文本。因此,我们可以使用此格式化的日期字符串:
#!/usr/bin/perl $date = '03/26/1999'; $date =~ s#(\d+)/(\d+)/(\d+)#$3/$1/$2#; print "$date"; This will produce following result 1999/03/26
使用\G断言
\G断言,让您可以继续搜索从最后一个匹配发生的点。
例如,在下面的代码,我们使用的\G,使我们可以搜索到正确的位置,然后提取一些信息,而无需创建一个更复杂的,单一的正则表达式:
#!/usr/bin/perl $string = "The time is: 12:31:02 on 4/12/00"; $string =~ /:\s+/g; ($time) = ($string =~ /\G(\d+:\d+:\d+)/); $string =~ /.+\s+/g; ($date) = ($string =~ m{\G(\d+/\d+/\d+)}); print "Time: $time, Date: $date\n"; This will produce following result Time: 12:31:02, Date: 4/12/00
\G断言,其实只是元符号相当于pos函数,所以正则表达式之间的调用,您可以继续使用pos,甚至修改pos的值(因此\ G)的使用pos作为一个lvalue子程序:
正则表达式中的变量
正则表达式的变量,包括$,包含匹配无论最后的分组匹配; $&, 其中包含整个匹配的字符串; $`, 其中包含匹配字符串前的一切; 和$', 其中包含匹配的字符串后的一切。
下面的代码演示的结果:
#!/usr/bin/perl
$string = "The food is in the salad bar";
$string =~ m/foo/;
print "Before: $`\n";
print "Matched: $&\n";
print "After: $'\n";
# www.yiibai.com
This code prints the following when executed:
Before: The
Matched: foo
After: d is in the salad bar