我想用每行末尾的Windows CRLF替换UTF-8编码的AssemblyInfo.cs中的这些行
<<<<<<< HEAD
[assembly: AssemblyVersion("2.0.0.0")]
[assembly: AssemblyFileVersion("2.0.0.0")]
=======
[assembly: AssemblyVersion("1.1.0.0")]
[assembly: AssemblyFileVersion("1.1.0.0")]
>>>>>>> v1_final_release
这些
[assembly: AssemblyVersion("2.0.0.0")]
[assembly: AssemblyFileVersion("2.0.0.0")]
为此,我有一个powershell脚本,它将解析所有文件并进行替换。
我在regex101中准备的正则表达式为this one,可在101上使用:
<<<<<<<\sHEAD\n\[assembly:\sAssemblyVersion\("2\.0\.0\.0"\)\]\n\[assembly:\sAssemblyFileVersion\("2\.0\.0\.0"\)\]\n=======\n\[assembly:\sAssemblyVersion\("1\.1\.0\.0"\)\]\n\[assembly: AssemblyFileVersion\("1\.1\.0\.0"\)\]\n>>>>>>>\sv1_final_release
我无法在新行上使-replace工作。
但是,仅定位<<<<<<<\sHEAD
时,它会匹配并执行替换。
以下所有变体均失败:
<<<<<<<\sHEAD\n\[assembly:
没有错误,没有替代<<<<<<<\sHEAD\r\n\[assembly:
没有错误,没有替代<<<<<<<\sHEAD
r n\[assembly:
没有错误,没有替代,写主机将其打印为
<<<<<<<\sHEAD
\[assembly:
与/gm
或(*CRLF)
无关
我的powershell信息说明:
$ConflictVersionRegex = "<<<<<<<\sHEAD\n\[assembly:\sAssemblyVersion\(`"2\.0\.0\.0`"\)\]\n\[assembly:\sAssemblyFileVersion\(`"2\.0\.0\.0`"\)\]\n=======\n\[assembly:\sAssemblyVersion\(`"1\.1\.0\.0`"\)\]\n\[assembly: AssemblyFileVersion\(`"1\.1\.0\.0`"\)\]\n>>>>>>>\sv1_final_release"
$ConflictVersionRegexTest = "<<<<<<<\sHEAD`r`n\[assembly:"
$fileContent = Get-Content($filePath)
$filecontent = $filecontent -replace $ConflictVersionRegexTest, $AssemblyNewVersion
[System.IO.File]::WriteAllLines($filePath, $fileContent, $Utf8NoBomEncoding)
我想念什么?为什么不替换呢?
非常感谢
答案 0 :(得分:1)
根据Poutrathor(OP)的反馈,存在两个问题:
主要问题是 Get-Content($filePath)
(应写为
Get-Content $filePath
[1 ] )逐行读取文件 ,当捕获到变量中时,该文件将生成行数组。
-replace
然后分别在每个输入行上 进行操作,这意味着跨行的正则表达式将不匹配任何内容。
Get-Content -Raw
(PSv3 +)将文件整体 读取为单多行字符串。其次,您提到需要将 regex 换行符(行尾)转义序列(\n
)(LF)替换为其 PowerShell 字符串插值副本(`n
)-请注意,PowerShell使用了`
,即 backtick 作为转义字符:
请注意,只有在替换字符串中才有必要,以便在输出中创建实际的,文字的换行符(换行符) -与将正则表达式构造\n
用于匹配换行符相反。
但是,在Windows中,换行符通常是CRLF 序列 ,即紧随其后的是CR(\r
,`r
)通过LF(\n
/ `n
)-即 \r\n
/ `r`n
-而在类似Unix的平台上,它们只是 LF, \n
/ `n
。
\r?\n
以跨平台兼容的方式匹配换行符。因此:
在您的 regex 中,您可以在\r\n
和`r`n
之间选择 ,但请注意:
`r`n
仅在双引号 "..."
字符串中起作用。\r\n
(Windows)/ { {1}}(Unix)/ \n
(与平台无关)-这样一来,就不会混淆PowerShell内插字符串的哪些部分以及正则表达式引擎解释了哪些部分。< / li>
在您的替换字符串中,在\r?\n
中使用`r`n
创建实际的换行符。
作为使用转义序列替代代表换行符的替代方法,您可以使用here-strings方便地定义具有实际换行符(换行符)的多行字符串 ,如Paweł Dyl's answer所示,但有一个腔室:
[1]您的调用看起来像.NET method 调用,尽管在这种情况下它可以正常工作,但应避免这种语法混淆:PowerShell cmdlet和函数的调用方式类似于< em> shell 命令:不带括号("..."
),并带有空格分隔的参数。
答案 1 :(得分:0)
请参阅以下演示:
$newText = @'
[assembly: AssemblyVersion("2.0.0.0")]
[assembly: AssemblyFileVersion("2.0.0.0")]
'@
$src = @'
<<<<<<< HEAD
[assembly: AssemblyVersion("2.0.0.0")]
[assembly: AssemblyFileVersion("2.0.0.0")]
=======
[assembly: AssemblyVersion("1.1.0.0")]
[assembly: AssemblyFileVersion("1.1.0.0")]
>>>>>>> v1_final_release
Other lines and second instance
<<<<<<< HEAD
[assembly: AssemblyVersion("2.0.0.0")]
[assembly: AssemblyFileVersion("2.0.0.0")]
=======
[assembly: AssemblyVersion("1.1.0.0")]
[assembly: AssemblyFileVersion("1.1.0.0")]
>>>>>>> v1_final_release
Some other lines
'@
$src -replace ('<<<<<<< HEAD\s+',
'\[assembly: AssemblyVersion\("2\.0\.0\.0"\)\]\s+',
'\[assembly: AssemblyFileVersion\("2\.0\.0\.0"\)\]\s+'+
'=======\s+'+
'\[assembly: AssemblyVersion\("1\.1\.0\.0"\)\]\s+',
'\[assembly: AssemblyFileVersion\("1\.1\.0\.0"\)\]\s+'+
'>>>>>>> v1_final_release'),$newText
此外,请确保将您的内容读为一个大字符串。可以使用Get-Content $path -Raw
或[System.IO.File]::ReadAllText($path)
来实现。