前言 :
目前為止我們只知道如何進行樣式比對, 但正規表示式也可以用來改變文字. 透過接下來的介紹, 你就可以先用樣式比對出一段文字, 接著把它們換掉.
以 s/// 進行置換 :
如果你要進行搜尋並取代 (search and replace), 你可以使用 Perl 的 s/// 置換運算符. 此運算符會對所指定的樣式進行比對, 然後把比對到的部分代換成所指定的字串 :
如果比對失敗, 什麼事也不會發生, 變數也不受影響. 當然樣式 (Pattern) 與代換字串還可以更複雜. 底下的代換字串用到了第一個比對變數, 也就是 $1 :
s/// 會傳回有用的布林值 ; 它在替換成功時為真, 否則為假.
- 以 /g 進行全域替換
在上面例子中, 即使有其他可以代換的部分, s/// 還是只會比對一次代換. 當然這是預定的行為. 你可以使用 /g 修飾符讓 s/// 進行所有可能, 互不重疊的代換 :
一個常見的全域代換應用是縮減空白, 也就是將任何連續的空白轉換成單一空格 :
接著你可能想問怎麼縮減開頭與結尾的空白, 這很簡單參考如下 :
至於簡潔的寫法則是使用擇一比對的技巧並配合上 /g 修飾符, 參考如下 :
- 不同的界定符號
就像 m// 與 qw// 一樣, 我們也可以改變 s/// 的界定符號(delimiter). 但是置換運算會用到三個界定符號, 所以情況有點複雜.
若是一般沒有左右之分 (分成對) 的字符, 用法便跟斜線一樣, 只用三個就可以, 範例如下 : (使用 # 當界定符)
但如果使用有左右之分的成對字符, 就必須使用兩對 : 一對用於包住樣式, 一對用於包住代換字串. 此狀況下, 包住樣式與字串的界定字符不需要相同. 事實上, 包住字串的界定符甚至可以用非成對的界定符號, 範例如下 :
- 選項修飾符
不僅是 /g 修飾符, 置換運算符也可以使用我們在一般樣式比對所到的 /i, /x 與 /s 修飾符 :
- 繫結運算符
同在使用 m// 時提到過, 我們可以用繫結運算符為 s/// 選擇不同的目標 :
- 大小寫轉換
在置換運算中, 你通常會想讓所代換的單字具有適當的大小寫. 這很容以用 Perl 做到 ; 只要使用到某些倒斜線規避序列就搞定. \U 規避序列會將其後的所有字串轉換成大寫 :
同理 \L 規避序列會將其後的字符轉成小寫. 預設上它們會影響之後全部的(代換)字串, 不然你也可以用 \E 來關閉大小寫轉換功能 :
使用小寫形式 (\u 與 \l) 只會影響之後的第一個字符. 你甚至可以將它們併用. 譬如你可以使用 \u 與 \L 來表示 "全部轉小寫, 但首字母大小" :
split 函式 :
一個會用到正規表示式的函示 split (split up a string using a regexp delimiter) , 它會根據分隔字符切開一個字串. 這對處理以跳格, 冒號, 空白或是任意符號所分隔的資料相當有用. 只要你能將分隔字符寫成樣式, 就可以使用 split. 它的用法如下 :
@fields = split /seperator/, $string;
split 函式將會以作為分隔符的樣式掃過指定字串 $string, 並且傳回該樣式所分隔出來的一串欄位 (子字串). 下面以冒號為分隔符作為範例 :
如果兩個分隔符放在一起, 就會產生空的欄位. 這裡有個規則要注意 : split 會保留開頭處的空欄位, 卻會捨棄結尾處的空欄位. 例如 :
split 預設會以空白字符拆開 $_ :
join 函式 :
join (join a list into a string using a separator) 函式並沒有用到樣式, 而起所達成的效果與 split 恰好相反 ; split 會將字串分解為數個片段 (子字串), 而 join 會將這些片段黏合成一個字串. 它的用法如下所示 :
my $result = john $glue, @pieces;
你可以將 join 的第一個引數想成 黏膠 (glue), 它可以是任何字串. 其餘的引數則是一串片段. join 會把黏膠放進每個片段之間, 並且回傳所得到的字串 :
雖然 split 與 join 常常搭配使用, 但是請別忘記 join 的第一個引數是字串, 而不是樣式!
串列語境下的 m// :
使用 split 時, 樣式的意義是分隔符 ; 也就是說資料中沒有用處的部分. 但是有時候寫下想要的部分反而比較簡單. 在串列語境下使用樣式比對運算符 (m//) 時, 如果比對成功, 其傳回值為所有比對變數的內容所構成的串列; 如果比對失敗, 則會傳回空字串 :
這麼一來就可以輕鬆為那些可能會在下一次樣式繼續沿用的 "比對變數" 取一些好記且好用的名字. 你之前在 s/// 的例子中使用的修飾符 \g 同樣也可以在 m// 上使用. 其效果就是讓樣是能夠比對的更多字串. 下面例子具有一對圓括號的樣式, 會在每一次比對成功時傳回一分記憶 :
如果不只一對圓括號, 那麼每次成功比對, 就可能傳回一個以上的字串. 假設我們想要把一個字串變成雜湊, 就可以這樣做 :
每成功比對一次, 就回傳回一對被記憶下來的值. 這一對的值剛好就成了新雜湊裡的 "鍵/值" 對了.
目前為止我們只知道如何進行樣式比對, 但正規表示式也可以用來改變文字. 透過接下來的介紹, 你就可以先用樣式比對出一段文字, 接著把它們換掉.
以 s/// 進行置換 :
如果你要進行搜尋並取代 (search and replace), 你可以使用 Perl 的 s/// 置換運算符. 此運算符會對所指定的樣式進行比對, 然後把比對到的部分代換成所指定的字串 :
- $_ = "He's out bowling with John tonight.";
- s/John/Peter/; # 用 Peter 取代 John
- print "$_\n";
- $_ = "He's out bowling with John tonight.";
- s/with (\w+)/against $1 team/;
- print "$_\n";
- 以 /g 進行全域替換
在上面例子中, 即使有其他可以代換的部分, s/// 還是只會比對一次代換. 當然這是預定的行為. 你可以使用 /g 修飾符讓 s/// 進行所有可能, 互不重疊的代換 :
- $_ = "home, sweet home!";
- s/home/cave/g;
- print "$_\n";
- $_ = "Input data\t may have extra whitespace.";
- s/\s+/ /g;
至於簡潔的寫法則是使用擇一比對的技巧並配合上 /g 修飾符, 參考如下 :
- 不同的界定符號
就像 m// 與 qw// 一樣, 我們也可以改變 s/// 的界定符號(delimiter). 但是置換運算會用到三個界定符號, 所以情況有點複雜.
若是一般沒有左右之分 (分成對) 的字符, 用法便跟斜線一樣, 只用三個就可以, 範例如下 : (使用 # 當界定符)
但如果使用有左右之分的成對字符, 就必須使用兩對 : 一對用於包住樣式, 一對用於包住代換字串. 此狀況下, 包住樣式與字串的界定字符不需要相同. 事實上, 包住字串的界定符甚至可以用非成對的界定符號, 範例如下 :
- 選項修飾符
不僅是 /g 修飾符, 置換運算符也可以使用我們在一般樣式比對所到的 /i, /x 與 /s 修飾符 :
- 繫結運算符
同在使用 m// 時提到過, 我們可以用繫結運算符為 s/// 選擇不同的目標 :
- 大小寫轉換
在置換運算中, 你通常會想讓所代換的單字具有適當的大小寫. 這很容以用 Perl 做到 ; 只要使用到某些倒斜線規避序列就搞定. \U 規避序列會將其後的所有字串轉換成大寫 :
- $_ = "I saw John with Peter.";
- s/(john|peter)/\U$1/gi;
- $_ = "I saw John with Peter.";
- s/(\w+) with (\w+)/\U$2\E with $1/i;
split 函式 :
一個會用到正規表示式的函示 split (split up a string using a regexp delimiter) , 它會根據分隔字符切開一個字串. 這對處理以跳格, 冒號, 空白或是任意符號所分隔的資料相當有用. 只要你能將分隔字符寫成樣式, 就可以使用 split. 它的用法如下 :
@fields = split /seperator/, $string;
split 函式將會以作為分隔符的樣式掃過指定字串 $string, 並且傳回該樣式所分隔出來的一串欄位 (子字串). 下面以冒號為分隔符作為範例 :
如果兩個分隔符放在一起, 就會產生空的欄位. 這裡有個規則要注意 : split 會保留開頭處的空欄位, 卻會捨棄結尾處的空欄位. 例如 :
split 預設會以空白字符拆開 $_ :
join 函式 :
join (join a list into a string using a separator) 函式並沒有用到樣式, 而起所達成的效果與 split 恰好相反 ; split 會將字串分解為數個片段 (子字串), 而 join 會將這些片段黏合成一個字串. 它的用法如下所示 :
my $result = john $glue, @pieces;
你可以將 join 的第一個引數想成 黏膠 (glue), 它可以是任何字串. 其餘的引數則是一串片段. join 會把黏膠放進每個片段之間, 並且回傳所得到的字串 :
雖然 split 與 join 常常搭配使用, 但是請別忘記 join 的第一個引數是字串, 而不是樣式!
串列語境下的 m// :
使用 split 時, 樣式的意義是分隔符 ; 也就是說資料中沒有用處的部分. 但是有時候寫下想要的部分反而比較簡單. 在串列語境下使用樣式比對運算符 (m//) 時, 如果比對成功, 其傳回值為所有比對變數的內容所構成的串列; 如果比對失敗, 則會傳回空字串 :
- $_ = "Hello there, neighbor!";
- my($first, $second, $third) = m/(\S+) (\S+), (\S+)/;
- print "$second is my $third\n";
如果不只一對圓括號, 那麼每次成功比對, 就可能傳回一個以上的字串. 假設我們想要把一個字串變成雜湊, 就可以這樣做 :
- my $data = "Lee John Ken Wang";
- my %last_name = ($data =~ m/(\w+) (\w+)/g);
This message was edited 3 times. Last update was at 28/08/2010 16:55:56
沒有留言:
張貼留言