我有一个在文件中执行正则表达式替换的函数。问题是,它在它接触的每个文件的开头添加了一个字符(0x00)(即使是那些它没有找到匹配的!)。由于我正在编辑csproj文件,MSBuild给了我这个错误:
error MSB4025: The project file could not be loaded. '.', hexadecimal value 0x00, is an invalid character. Line 2, position 1.
下面是我的函数:
function fileStringRegExReplace ([string] $fileToChange, [string] $oldString, [string] $newString) {
echo "f" | xcopy "$fileToChange" "$fileToChange.og.cs" /Y /Q
$file = Get-Content "$fileToChange.og.cs" |
Foreach-Object {
$_ -replace $oldString, $newString
} |
Out-File "$fileToChange"
Remove-Item "$fileToChange.og.cs"
}
我如何替换我想要的行而不改变文件的任何其他部分?
听起来像是在文件的开头写一个BOM。您可以通过out-file
上的-Encoding ASCII
参数将编码设置为ASCII(没有BOM)。
Out-File的默认编码是Unicode
,这是windows对UTF-16的说法。当只写入来自ASCII集的字符时,UTF-16基本上具有在每个字符前面添加0x00
字节的效果。这就解释了为什么visual studio总是抱怨0x00
字节。
您试图修改的csproj文件的XML声明自己为UTF-8,因此使用Out-File中的-Encoding UTF8
选项。
不要使用ASCII编码,这将导致问题一旦csproj文件得到一个非ASCII字符。
我也有同样的问题,在使用ForEach
替换文本后,我遇到了问题。
对于我的解决方案,我只是想找到最后一个</Target>
并添加附加另一个<Target></Target>
。
我尝试了这种方法,由于某种原因,文件大小增加了一倍,并且在Line: 2, Position: 1
的0x00
错误上也失败了。
我必须在这个解决方案上归功于@Matt,因为我可能不会自己弄清楚正则表达式:https://stackoverflow.com/a/28437855/740575
这使我可以优雅地不使用ForEach
方法。你应该在这个解决方案中找到你的答案。
$replaceVar = "<Target> ... </Target" ;
# NOTE: -Raw will read the entire file in as a string, without doing that
# everything gets read in as an array of lines
$file = Get-Content file.csproj -Raw ;
$newFile = $file -replace "(?s)(.*)</Target>(.*)", "$1$replaceVar$2" ;
# csproj is UTF8
$newFile | Out-File -Encoding UTF8 "new.csproj" ;
解决方案适用于Visual Studio和msbuild.exe
。
尝试将out-file替换为set-content。