.NET 正則引擎支援 RightToLeft 選項,讓匹配掃描方向從「最右端」開始向左進行。這在「取得最後 N 個字元」、「解析反向格式字串」、「從尾部提取檔案副檔名」等場景極其高效。PowerShell 透過 [regex]::new() 建構子即可啟用此功能。本文詳細說明語法、核心範例、效能優勢與實戰應用模式。
# 建立啟用 RightToLeft 的 Regex 物件
$regex = [System.Text.RegularExpressions.Regex]::new('pattern', 'RightToLeft')
# 或使用選項列舉 (可組合其他選項)
$regex = [regex]::new('pattern', [System.Text.RegularExpressions.RegexOptions]::RightToLeft)
# 執行匹配
$match = $regex.Match('input string')
# 後續匹配
$nextMatch = $match.NextMatch()
$x = [regex]::new('\d{2}', 'RightToLeft')
$m = $x.Match('abcd22')
$m.Value # "22" (從右往左,第一個遇到的兩位數字)
$m.Index # 4 (索引位置仍為從左起算的 0-based)
關鍵行為:
Match.Index 仍回傳 從左起算 (0-based) 的位置,不會反轉。NextMatch() 會繼續向左尋找下一個匹配。function Get-LastChars {
param($String, $Count)
$rx = [regex]::new(".{$Count}$", 'RightToLeft') # $ 仍匹配字串末尾
$m = $rx.Match($String)
$m.Success ? $m.Value : $String
}
Get-LastChars 'abcdefghij' 3 # "hij"
$path = 'C:\Projects\MyApp.v2.1.4.zip'
$rx = [regex]::new('\.([^.]+)$', 'RightToLeft')
$m = $rx.Match($path)
$m.Groups[1].Value # "zip"
# 對比:一般 Regex 從左匹配需用貪婪/非貪婪控制,RightToLeft 直覺得多
$version = '1.2.3.4.5'
# 取得最後兩段: 4.5
$rx = [regex]::new('(\d+)\.(\d+)$', 'RightToLeft')
$m = $rx.Match($version)
$m.Groups[1].Value # "4"
$m.Groups[2].Value # "5"
$csv = 'a,b,c,d,e,f'
$rx = [regex]::new(',', 'RightToLeft')
$m = $rx.Match($csv)
$m.Index # 9 (最後一個逗號位置,0-based)
# 取得最後一欄
$lastField = $csv.Substring($m.Index + 1) # "f"
$log = @"
2024-01-01 INFO Start
2024-01-01 WARN Retry
2024-01-01 ERROR Failed
"@
$rx = [regex]::new('^\s*\S+.*$', 'RightToLeft, Multiline')
$m = $rx.Match($log)
$m.Value # "2024-01-01 ERROR Failed"
$longStr = 'x' * 100000 + 'TARGET' + 'y' * 100000
# 一般 Regex (從左掃描 10 萬字元才找到)
$rx1 = [regex]::new('TARGET')
Measure-Command { $rx1.Match($longStr) }.TotalMilliseconds # ~2-5 ms
# RightToLeft (從右掃描 6 字元即找到)
$rx2 = [regex]::new('TARGET', 'RightToLeft')
Measure-Command { $rx2.Match($longStr) }.TotalMilliseconds # ~0.01 ms (200x 快)
| 場景 | 一般 Regex | RightToLeft | 優勢 |
|---|---|---|---|
| 目標在字串末尾 | 掃描全字串 | 立即命中 | 極大 |
| 目標在字串開頭 | 立即命中 | 掃描全字串 | 一般較好 |
| 需所有匹配 (從右到左) | Match + NextMatch 從左 | Match + NextMatch 從右 | 視需求 |
| 索引計算 | 直覺 | Index 仍從左算 | 需注意 |
$ 行為改變:$ 仍匹配字串絕對末尾 (或 Multiline 時的行末),不會變成「從右掃描的起點」。^ 匹配開頭:在 RightToLeft 下,^ 仍匹配字串開頭 (或行首),只是引擎從右往左嘗試匹配整個模式。Match.Index 永遠是 從左起算,若需從右長度計算:$str.Length - $m.Index - $m.Length。RightToLeft 不改變此限制。# 忽略大小寫 + 從右往左 + 多行模式
$options = [System.Text.RegularExpressions.RegexOptions]::RightToLeft `
-bor [System.Text.RegularExpressions.RegexOptions]::IgnoreCase `
-bor [System.Text.RegularExpressions.RegexOptions]::Multiline
$rx = [regex]::new('pattern', $options)
RightToLeft,效能提升可達數百倍。Index 從左算,必要時轉換為從右偏移。RightToLeft 行為與直覺偶有出入 (特別配合 ^$、Lookaround),務必用實際資料測試。RightToLeft 是 .NET 正則引擎的一顆隱藏寶石,善用它能解決「從尾部提取資訊」類問題時的效能與可讀性雙重痛點,是 PowerShell 進階文本處理工具箱中的必備利器。