regex - 正则表达式替换powershell中的多行
问题描述
我想在每行末尾用 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 中准备的正则表达式是这个并且适用于 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
rn\[assembly:
没有错误没有替换,write-host 将其打印为<<<<<<<\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)
我错过了什么?为什么不替换?
非常感谢
解决方案
根据 Poutrathor(OP)的反馈,存在两个问题:
主要问题是
Get-Content($filePath)
(应该写为Get-Content $filePath
[1])逐行读取文件,当在变量中捕获时会产生一个行数组。然后单独
-replace
对每个输入行进行操作,这意味着跨行正则表达式不会匹配任何内容。- 解决方案:使用
Get-Content -Raw
(PSv3+) 将文件作为一个整体读入单个多行字符串。
- 解决方案:使用
其次,您提到需要将正则表达式换行符(行尾)转义序列(
\n
)(LF)替换为其PowerShell字符串插值对应项(`n
) -请注意,PowerShell使用`
反引号作为转义字符:请注意,这仅在替换字符串中是必需的,以便在输出上创建实际的文字换行符(换行符)- 而不是使用正则表达式构造来匹配换行符。
\n
但是,在 Windows 上,换行符通常是 CRLF序列,即 CR (
\r
,`r
) 紧跟 LF (\n
/`n
) - 即\r\n
/`r`n
- 而在类 Unix 平台上它们只是LF,\n
/`n
。- 如果您不确定给定输入具有哪种样式的换行符,请使用
\r?\n
以跨平台兼容的方式匹配换行符。
如果您不关心输入有哪些特定的换行符,那么按照习惯,可以安全地有条不紊地使用。
- 如果您不确定给定输入具有哪种样式的换行符,请使用
所以:
在您的regex中,在您的情况下,您可以在and之间进行选择,请注意:
\r\n
`r`n
`r`n
仅适用于双引号"..."
字符串。- 通常最好使用文字、单引号字符串来存储正则表达式——这需要使用
\r\n
(Windows)/\n
(Unix)/\r?\n
(平台不可知论) ——这样就不会混淆 PowerShell 的哪些部分在前面与. 正则表达式引擎解释了哪些部分。
在您的替换字符串中,使用
`r`n
inside"..."
创建实际的换行符。
作为使用转义序列表示换行符的替代方法,您可以使用here-strings方便地定义具有实际换行符(换行符)的多行字符串,如Paweł Dyl 的回答所示,但有一个警告:
- Here-strings 总是具有与封闭脚本文件相同的换行符样式,这意味着:
- 仅当输入恰好与脚本文件具有相同样式的换行符时,基于此处字符串的正则表达式才会匹配。
- 基于 here-string 的替换字符串将始终使用脚本文件的换行符样式。
[1] 您的调用看起来像一个 .NET方法调用,虽然它恰好在这种情况下工作,但应避免此类语法混淆:PowerShell cmdlet 和函数像shell命令一样被调用:不带括号 ( (...)
) 并使用空格分隔的参数。
推荐阅读
- laravel - 如何使用模态 Laravel 5.8 更新特定行
- reactjs - 检测鼠标点击并在 React 中更改状态
- java - 在 Java 中,在对其应用流函数链之前检查集合是否为空是否可以提高性能?
- c++ - EmfToWmfBits api 总是返回 0
- reactjs - 设置值后无法单击复选框
- c++ - 如果我们在 c++ 中 basic_string 达到 max_size 之后再添加一个字符会发生什么
- asp.net-mvc-4 - 在 IIS 8 上允许 1000 多个并发用户用于 ASP.NET MVC Web 应用程序
- python - 无法在python中使用正则表达式从字符串中获取整个链接
- javascript - 如何对json数据进行分类
- mysql - 在heroku上进行狂欢迁移的Mysql语法错误