的powershell正则表达式与问题线锚定件的的powershell 2对比的powershell 5端

问题描述:

鉴于以下代码:的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)' - 。。?看我怎么回答。 –

这与正则表达式或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

的问题与您'(?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/)。 –