2017-10-19 49 views
1

鑑於以下代碼:的powershell正則表達式與問題線錨定件的的powershell 2對比的powershell 5端

$inputString = "`r`n#cmakedefine BREAK_THE_CODE`r`n" 
$match = '(?m)^(.*?)#cmakedefine(.*?)$' 
$replace = 'hello $1#undef$2 goodbye ' 
$retVal = $inputString -replace $match,$replace -join "`r`n" 
Write-Host $retVal 

Powershell的5產生以下的(預期的)輸出:

hello #undef BREAK_THE_CODE goodbye 

Powershell的2產生(意外)輸出:

goodbye def BREAK_THE_CODE 

任何人都知道爲什麼?或者有一個解決方法。如果使用[regex ::],我會更加一致。我需要兩個版本才能產生相同的結果。對於它的價值,你好和再見將最終成爲/**/,但我試圖避免混淆與任何可以解釋爲特殊字符的問題。

編輯:下面馬特的答案是詳細說明了兩個Powershell的版本產生相同的輸出,[CR][LF]hello #undef BREAK_THE_CODE[CR] goodbye [LF] 和版本之間的明顯差異實際上是ISE與不ISE和Write-Host。所以這裏的根本問題是我的正則表達式剛剛壞掉,儘管我仍然不知道這是爲什麼。

我結束了:

$match = "(?m)^(.*?)#cmakedefine([^\r\n]*)" 
$replace = '/* $1#undef$2 */' 

作爲一個小工具條,對VS 2015年IDE幫助(這幾乎可以肯定使用相同的正則表達式引擎)列出\r?$爲線錨的正常結束: https://msdn.microsoft.com/en-us/library/2k3te2cs.aspx

通過捕獲它的\r部分,可以使該錨點工作,我最初的做法是,但我首選Wiktor的解決方案。

+1

您可以大大提升'(*)(\'R)' - 。。?看我怎麼回答。 –

回答

4

這與正則表達式或PS版本沒有任何關係,但Write-Host正在處理字符串中中的那個孤獨回車。我也可以在PowerShell 2.0和5.0中重現此操作,但是由於它是一個不同的環境,因此不是ISE而是。你可以將你的發現減少到這個陳述。

write-host "Hello Matt`rBagel" 

它應打印「你好馬特百吉餅」,而是打印「百吉餅馬特」回車復位主機cursorposition,然後繼續打字。所以它打印出你好馬特,但隨後用「百吉餅」覆蓋了「你好」。

Wikipedias definition of CR將有助於解釋當控制字符本身時這是設計狀態。

回車,有時被稱爲一個盒返回並通常簡稱爲CR,或返回,是用於設備的位置重置到文本行的開始控制字符或機構

你不會看到這一點,如果你只是用Write-Output或只是$retVal在命令行上。去除孤獨的CR也會解決這個問題。

write-host ("Hello Matt`rBagel" -replace "`r(?<!`n)") 

你有此問題的原因是,它出現在(.*?)$錨定在"`n"所以捕獲組在消費回車。如果這是你在真實數據中看到的東西,那麼你需要以某種方式解釋它。

+0

啊,很好。這是有用的信息,儘管我不幸處於函數中,寫入輸出被吞噬。 – zzxyz

+0

然後更換寂寞CR ....... – Matt

+0

所以這是另外一個問題。我不知道爲什麼我的正則表達式被破壞:) – zzxyz

2

的問題與您'(?m)^(.*?)#cmakedefine(.*?)$'模式是,.符號任何字符,但一個LF(只有換行符)相匹配,並且(?m)修改使得$錨比賽之前LF權,可能的CR之後。這意味着,在CR符號存在於捕獲組2

看你的字符串的末尾:

<CR><LF> 
#cmakedefine BREAK_THE_CODE<CR><LF> 
|------------- MATCH ---------| 
||   |-----Group2------| 

組1值是空的,第2組包含BREAK_THE_CODE。所以,CR變得「孤獨」,如Matt explains

這裏是一個可能的修復,以[^\r\n]*匹配比CR和LF其他0或多個字符替換最後懶惰點圖案(和$變得多餘然後):

$match = '(?m)^(.*?)#cmakedefine([^\r\n]*)' 
$replace = 'hello $1#undef$2 goodbye ' 

這裏是一個regex demo(不幸的是所有的值在表中有從空白修剪,但現在必須很好地工作)

+0

這是\ r \ n行結束一個典型的問題?我不記得跟其他正則表達式引擎碰上它,但也許我是用linux行工作的結局每次。 – zzxyz

+0

.NET不是唯一的一個。例如。 [Python也一樣](https://ideone.com/4O9fDD)。然而,它是[未在與JS情況](https://jsfiddle.net/x4t16au3/)。 –