正則表達式是一個字符串的字符定義視圖的模式或多模式。在Perl的正則表達式的語法是什麼,你會發現在其他正則表達式,如sed,grep和awk的支持程序非常相似。
運用正則表達式的基本方法是使用結合的經營模式=〜和!〜。第一個是一個測試操作符,第二是一個賦值操作符。
在每種情況下斜線作為正則表達式(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.gitbook.net 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.gitbook.net \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,使我們可以搜索到正確的位置,然後提取一些信息,而無需創建一個更複雜的,單一的正則表達式:
#!/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.gitbook.net
This code prints the following when executed:
Before: The
Matched: foo
After: d is in the salad bar