Powershell - 替换字符串中的多个 5 位子字符串

Powershell - Replace multiple 5-digit substrings in a string

我们有一些客户在支付发票时没有提及我们的 INV 前缀,因此我想将其添加到我们的 MT940 银行对帐单文件中。

:20: :25:MHAZNL2AXXX/0376603160 :28C:102/ :60F:C220525EUR5000,
:61:2204130413C336,52NMSCTOPF2500472627//GBBR001SCT TOPF2500472627
:86:17136 17364 17382 032022102402 WONG TONG SARL 1 RUESOMETHINGPARIS SOGEFRPPXXX NOT PROVIDED
:61:2204200420C406,02NMSCTOPF2500479378//GBCJ005SCT TOPF2500479378
:86:17486 17586 17697 17813 0320221054201 WONG TONG SARL 1RUE SOMETHINGPARIS SOGEFRPPXXX NOTPROVIDED

我需要它

:20: :25:MHAZNL2AXXX/0376603160 :28C:102/ :60F:C220525EUR5000,
:61:2204130413C336,52NMSCTOPF2500472627//GBBR001SCT TOPF2500472627
:86:INV17136 INV17364 INV17382 032022102402 WONG TONG SARL 1 RUESOMETHINGPARIS SOGEFRPPXXX NOT PROVIDED
:61:2204200420C406,02NMSCTOPF2500479378//GBCJ005SCT TOPF2500479378
:86:INV17486 INV17586 INV17697 INV17813 0320221054201 WONG TONG SARL 1RUE SOMETHINGPARIS SOGEFRPPXXX NOTPROVIDED

我也使用 switch 语句来匹配其他行,这就是我使用 switch 的原因。

switch -Regex -File c:\Temp\WONG.ged  {
    ':86:.+WING SENG.+'   { $_.replace('([1234567]\d{4}[ ])', "INV") }
    default               { $_ } # unrelated line, pass through
    } 

这似乎 work 但替换不起作用(如果我将 WONG 替换为 TEST 那么它就可以正常工作)。 我加了1234567防止匹配太多还是匹配太多

这里有几个问题:

  • 您需要使用支持正则表达式替换操作的 -replace 运算符,而不是 String.Replace 方法(参见 What's the difference between .replace and -replace in powershell?
  • 您的文本不包含 WING SENG,因此没有匹配项
  • 定义反向引用时,需要使用文字 $,因此要么使用单引号括起替换 'INV',要么转义反引号 "INV`"

这将产生预期的结果:

switch -Regex -File c:\Temp\WONG.ged {
 ':86:.+WONG TONG'   { $_ -replace '[1-7]\d{4} ', 'INV$&' }
 default             { $_ } # unrelated line, pass through
}

注意模式看起来有点不同:[1-7] 比冗长的 [1234567] 更短更精简,并且不需要用捕获组包围整个模式,您可以参考与 $& 反向引用的整体匹配。此外,无需在正则表达式末尾添加 .+

还有一个替代解决方案:

(Get-Content $filepath) -replace '(\G(?!^)|^(?=:86:.+WONG TONG))(.*?)([1-7]\d{4}(?!\S))', 'INV'

参见regex demo详情:

  • (\G(?!^)|^(?=:86:.+WONG TONG)) - 第 1 组:上一个成功匹配的结尾 (\G(?!^)) 或 (|) 字符串(此处为行)开始位置 (^) 紧跟 :86:,换行字符以外的任何一个或多个字符,尽可能多,然后是 WON TONG string
  • (.*?) - 第 2 组 (</code>):除换行字符外的任何零个或多个字符尽可能少</li> <li><code>([1-7]\d{4}(?!\S)) - 第 3 组 (</code>):从 <code>17 的数字,然后是字符串末尾或紧随其后的任意四位数字有一个空格。

(Get-Content $filepath)逐行读取文件,所以任何不匹配的行将原样输出,不受影响。