如果文本被换行符或标签打断,该如何替换?

时间:2019-04-25 08:17:17

标签: regex powershell

我从具有powershell的程序中读取了一个文件,并希望在那里替换某些字符串。例如,文件的内容如下所示:

<"#319",
    @"Sprache" =        "DE">

<F5@T@Z7@L1031>5<F5@T@Z7@L1033>)<F5@Z7@L1031><Tab>#319-10002

现在我想替换例如#319-10002的{​​{1}},这没问题。

Some Text

这些“变量”来自CSV文件,因此是动态的。有2种类型:

  1. #Number-Number
  2. #Number-Text

现在还存在行长超过80个字符的情况。然后,生成文件的程序会自动在80个字符后插入换行符。

$output = New-Object System.IO.StreamWriter (Join-Path -Path $outputPath -ChildPath "$outputName.ildoc")

Get-Content -Path (Join-Path -Path $inputPath -ChildPath "$inputName.ildoc") -ReadCount 512 | ForEach-Object {
    $value = $_

    foreach($entry in $csvInput.GetEnumerator()) {
        $value = $value -replace $entry.Name, $entry.Value
    }

    $output.Write((($value | Out-String) -replace "`r`n", "`n"))
}

$output.Close()

然后,还有字符串被标签打断的情况。如果文本在表中,并且文本长于列,则程序会自动在插入处插入<"#319", @"Sprache" = "DE"> <F5@T@Z1@L1031>3<F5@T@Z1@L1033>)<F5@Z1@L127><Tab><F5@Z1@L1031>Some more Text #3 19-10002 ,然后在换行处插入换行符。

<SR>

我现在非常茫然如何解决问题。您有解决办法的想法吗?

2 个答案:

答案 0 :(得分:0)

在应用替换项之前,您可以预处理文件
使用正则表达式删除Pos〜80和<SR>中断:

(Get-Content .\input.ildoc -raw) -replace '(?m)(?<=^.{79,})\r?\n' -replace '\<SR\>\r?\n'

这里有两个样本)

<"#319",
    @"Sprache" =        "DE">

<F5@T@Z1@L1031>3<F5@T@Z1@L1033>)<F5@Z1@L127><Tab><F5@Z1@L1031>Some more Text #319-10002
<Cell, Straddle = 2,
    Top Ruling Color =  16,
    Left Ruling Weight =    0.75,
    Left Ruling Color = 30,
    Left Ruling Visible =   no><!Page,
    Left Margin =       0.0039372 Inches,
    Right Margin =      0.0039372 Inches>
<"text:zentr">

#319-10002

答案 1 :(得分:0)

我认为您首先需要使用一些清理文件内容的正则表达式来解决此问题。

也许这会有所帮助:

首次通过以处理由换行符分隔的#Number-Number或#Number-Text

$content = $content -replace '(#)(?:\r?\n)*(\d+)(?:\r?\n)*([-\w]+)', '$1$2$3'

此更改

<F5@T@Z1@L1031>3<F5@T@Z1@L1033>)<F5@Z1@L127><Tab><F5@Z1@L1031>Some more Text #3
19-10002


<F5@T@Z1@L1031>3<F5@T@Z1@L1033>)<F5@Z1@L127><Tab><F5@Z1@L1031>Some more Text #3
20-TEXT

进入

<F5@T@Z1@L1031>3<F5@T@Z1@L1033>)<F5@Z1@L127><Tab><F5@Z1@L1031>Some more Text #319-10002

<F5@T@Z1@L1031>3<F5@T@Z1@L1033>)<F5@Z1@L127><Tab><F5@Z1@L1031>Some more Text #320-TEXT

第二遍处理<SR>,后跟换行符:

$content = $content -replace '(#[-\d]+)<SR>\r?\n([-\w]+)', '$1$2'

这会改变诸如

#319-10<SR>
002

进入

#319-10002

此后,应该不再分解要替换的元素。

将其放在一起,您可以尝试以下代码:

# get the content of the file as a single string including line breaks
$content = Get-Content -Path (Join-Path -Path $inputPath -ChildPath "$inputName.ildoc") -Raw

# remove garbage linebreaks
$content = $content -replace '(#)(?:\r?\n)*(\d+)(?:\r?\n)*([-\w]+)', '$1$2$3'
# remove garbage <SR>linebreaks
$content = $content -replace '(#[-\d]+)<SR>\r?\n([-\w]+)', '$1$2'

# split the content into an array of strings and loop through
for ($i = 0; $i -lt ($content -split '\r?\n').Count; $i++) {
    $line = $content[$i]
    foreach($entry in $csvInput.GetEnumerator()) {
        $line = $line -replace $entry.Name, $entry.Value
    }
    # overwrite the string element with the replaced value
    $content[$i] = $line
}

# finally write the updated array as string joined with '\n'
Set-Content -Path (Join-Path -Path $outputPath -ChildPath "$outputName.ildoc") -Value ($content -join '\n')