【问题标题】:Powershell regex replace unescaped double quote followed by line breakPowershell 正则表达式替换未转义的双引号,后跟换行符
【发布时间】:2021-05-03 04:08:10
【问题描述】:

我正在处理一个大型 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();
    }

【问题讨论】:

标签: regex powershell csv


【解决方案1】:

下一次,尝试构建一个Minimal, Reproducible Example(也为您自己),因为它可能有助于更好地理解问题。
一个常见的缺陷是标准 cmdlet Get-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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-24
    • 1970-01-01
    相关资源
    最近更新 更多