-- Start
我們在
括弧及後向引用 一節中瞭解到了括弧的兩種用途:分組和捕獲。
分組
事實上,正在運算式還一共提供了三種結構用於分組,如下:
| 元字元(Metacharacter) |
匹配(Matches) |
| (...) |
分組 |
| (?:...) |
分組 |
| (?>…) |
固化分組 |
它們之間有什麼區別呢? 我們先看一個例子吧。
#!/usr/bin/perlmy $testText = "#test#"; # 測試文本# 基準if($testText =~ m/#.*#/) {print "#.*# 匹配了 #test#\n";}# 測試 (...)if($testText =~ m/(#.*#)/) {print "(#.*#) 匹配了 $1\n";}# 測試 (?:...)if($testText =~ m/(?:#.*#)/) {print "(?:#.*#) 匹配了 $1\n";}# 測試 (?>...)if($testText =~ m/(?>#.*#>)/) {print "(?>#.*#>) 匹配了 $1\n";} else {print "(?>#.*#>) 無法匹配 #test#\n";}
運行結果:
#.*# 匹配了 #test#(#.*#) 匹配了 #test#(?:#.*#) 匹配了(?>#.*#>) 無法匹配 #test#
從結果中我們可以看出,(?:...) 只能用於分組,而 (...) 除了分組還捕獲了括弧中的內容。那 (?>...) 是什麼意思呢?(?>#.*#>) 為什麼無法匹配 #test# 呢?要想理解什麼是固化分組,我們必須深入Regex的匹配原理,我們在貪婪,非貪婪和佔有量詞的區別 一節中介紹了什麼是 佔有量詞,如果你理解了什麼是佔有量詞,那麼肯定知道了為什麼
(?>#.*#>) 無法匹配 #test#。
捕獲和後向引用
我們知道了括弧除了可以用於分組,還可以用於捕獲。我們為什麼要捕獲括弧中的內容呢? 主要原因是,在捕獲之後,我們可以通過後向引用來得到之前捕獲的內容,這在文本替換操作中非常重要,捕獲及後項引用的形式如下:
| 元字元(Metacharacter) |
匹配(Matches) |
| (...) |
捕獲 |
| \n |
引用第n個括弧中匹配的內容 |
| (?<name>...) |
命名捕獲 |
命名捕獲的意思是給捕獲的內容起個名字,稍後我們可以通過這個名字來引用其內容,而無需通過 \n 的形式來引用。Perl 和 Java 不支援命名捕獲。
--更多參見:Regex精萃
-- 聲 明:轉載請註明出處
-- Last Updated on 2012-05-13
-- Written by ShangBo on 2012-05-13
-- End