2023年4月11日 星期二

正則如何抓出所有雙引號並修改特定字串

正則如何抓出所有雙引號並修改特定字串

這個問題之前看PTT版討論可能好像是無解,不過今年因為GPT出了正則變得更容易使用了,不需要花大量時間,少樣本學習直接丟就有答案了。

這邊用的語言是 Powershell 可以直接打開終端機輸入就可以驗證了



匹配雙引號中的字串

先來個範例樣本

$csv_string = '"a", "b", "c"'

對應的代碼是

$csv_string = '"a", "b", "c"'
$pattern = '(?<=\")[^"\s]*(?=\")'
$matches = [regex]::Matches($csv_string, $pattern) | ForEach-Object { $_.Value }

$matches

如此一來就可以取出 abc 的陣列了,後面的 ForEach-Object { $_.Value } 只是把regex物件中的字串給抓出來而已


不過這有個問題如果字串是相連的 '"dd1"ffff"dd2"' 會抓到中間值,抓出三個連帶ffff也抓了。對於這個的解法是

$csv_string = '"dd1"ffff"dd2"'
$pattern = '(?<=\")[^"\s]*?(?=\"(?:[^"]*"[^"]*")*[^"]*$)'
$matches = [regex]::Matches($csv_string, $pattern) | ForEach-Object { $_.Value }

$matches

這樣可以準確避開了,不過我想如果情況再複雜一點可能也會出bug,在長下去也沒意義了,太長了無法閱讀之外也容易埋雷,依照情況適當選用就好。



匹配雙引號中的字串並取代替特定字串

進階一點換一個範例,這次除了要抓出雙引號之外還附加要修改雙引號內特定的字串

$csv_string = '"ahuchgnde@#", "gokerjorb", "eokgchgjoec", chg, "chg"'

以這個字串來說我要把chg改成[CHG],並且設置了檢查項目其中有一個chg是不帶雙引號的

$csv_string = '"ahuchgnde@#", "gokerjorb", "eokgchgjoec"'
$pattern = '((?<=")[^"]*?)chg(([^"]*?)(?="))'
$replacement = '$1[CHG]$3'

$new_csv_string = $csv_string -replace $pattern, $replacement
$new_csv_string



匹配雙引號中的雙引號

難的地方在於雙引號沒辦法區分頭尾,雖然用看得看的出來但是真的要寫實在是無從下手。

經過反覆確認如果是沒有給定條件是判斷不出來的,這邊用CSV的文本當範例可以用逗號輔助判斷頭尾雙引了,沒這逗號replace是做不到的。

$csv_string = 'some data,"AAA""這裡""AA", "BBBBBB",more data,"", "CCCDDD""EEE"""'

以這個範例來說我要消除雙引號中的雙引號,消除到只剩一個

$csv_string = 'some data,"AAA""這裡""AA", "BBBBBB",more data,"", "CCCDDD""EEE"""'
$regex = '(?<=[^,])""(?=[^,])'
$csv_string = $csv_string -replace $regex, '"'
$csv_string

如此一來就可以抓出來了,如果要完全消除就把後面的雙引號留空白就好

不過這還是有個小問題是如果引號中的引號不是兩個一組出現,就無法處理了。試了很久沒出來估計是正則做不到了。




沒有留言:

張貼留言