regex - Powershell 正则表达式替换未转义的双引号,后跟换行符
问题描述
我正在处理一个大型 csv 文件,其中包含用双引号括起来的字段,其中的文本描述包含未转义的双引号,我需要用转义的双引号替换。我尝试使用以下正则表达式:(?<!^|",)("(?:$[^"])|"(?!,"|$))
它能够找到未转义的引号,除非它们后跟换行符。感激地收到解决此问题的任何帮助。
我知道 csv 格式不正确,但不幸的是无法控制,因此我需要能够更正格式以进行进一步处理。
例子:
"Field 1","Field 2","Field 3 "with unescaped quote"
followed by line break","Field 4"
需要变成:
"Field 1","Field 2","Field 3 ""with unescaped quote""
followed by line break","Field 4"
我正在使用的 Powershell 脚本如下:
[string]$path = 'C:\ ...'
[string]$directory = [System.IO.Path]::GetDirectoryName($Path);
[string]$strippedFileName = [System.IO.Path]::GetFileNameWithoutExtension($Path);
[string]$extension = [System.IO.Path]::GetExtension($Path);
[string]$newFileName = $strippedFileName + [DateTime]::Now.ToString("yyyyMMdd-HHmmss") + $extension;
[string]$newFilePath = [System.IO.Path]::Combine($directory, $newFileName);
$reader = New-Object 'System.IO.StreamReader'($path, $true);
$regex = [regex] '(?<!^|",)("(?:$[^"])|"(?!,"|$))'
$writer = [System.IO.StreamWriter] $newFilePath;
try{
while (($line = $reader.ReadLine()) -ne $null ){
$newline = $line -replace $regex, '""';
$writer.WriteLine($newline);
}
}
finally{
$reader.Close();
$writer.Close();
}
解决方案
下一次,尝试构建一个最小的、可重现的示例(也为您自己),因为它可能有助于更好地理解问题。
一个常见的缺陷是标准 cmdletGet-Content
读取行流 ( string[]
),其中每行本身不包含任何换行符,但在输出到显示或文件。您可以通过使用-Raw
参数来解决此问题,但这会将所有内容读入内存并可能使其比实际更复杂。
我怀疑您实际上想要查找不以双引号开头的行,这意味着前面的csv
行可能被截断。这意味着,在这种情况下,您希望将前一行与一个额外的双引号连接起来,重新插入换行符并添加当前行:
Get-Content .\Input.csv | Foreach-Object { $Previous = $Null } {
if ($_.StartsWith('"')) {
$Previous
$Previous = $_
} else {
$Previous += '"' + [Environment]::NewLine + $_
}
} { $Previous } | Set-Content .\Output.csv
推荐阅读
- javascript - 对于一堆带有 JS 或 Python 的 XHTML 文件,自动加载 XHTML 并单击一个按钮的最简单方法是什么?
- sql - 删除超过 1 个月的记录
- excel - 如何在excel中存储以“+”开头的文本?
- python - 当服务器返回这样的数据时,我该如何抓取?
- javascript - 当应用程序处于后台并且屏幕被锁定时,React-native-background 计时器在 15 分钟后停止工作
- python - 如何循环一个进程
- sql - C#获取gps数据sql到GPRMC插入
- c# - 如何将输入字符串转换为数据表
- jms - 对多个目的地/主题使用相同的 JMS ClientID
- ruby - 如何为 raise、rescue 块编写 rspec