regex - Powershell正则表达式替换两个相同字符之间的特定字符
问题描述
我正在尝试使用 Powershell 用分号分隔的文件中;
的管道替换分号|
,因此它是出现在双引号之间的一组特定分号"
。这是文件的示例,具体部分以粗体显示:
营地;巴西;AI;BCS GRU;;MIL-32011257;172-43333640;; "1975995;1972871;1975" ;FAC0088/21;3;20.000;24.8;25.000;.149;眼镜备件,;EXW;C;.00;EUR;
我试过使用-replace
,如下:
(Get-Content $file.PSPath) |
Foreach-Object { $_ -replace '".*(;).*"',"|" } |
但是,正则表达式不会用管道替换引号之间的分号。我尝试了其他几个正则表达式无济于事。我会怎么做才能做到这一点?
解决方案
您可以使用Regex.Replace
带有回调的方法作为替换参数:
$s = 'Camp;Brazil;AI;BCS GRU;;MIL-32011257;172-43333640;;"1975995;1972871;1975";FAC0088/21;3;20.000;24.8;25.000;.149;GLASSES SPARE PARTS,;EXW;C;.00;EUR;'
$rx = [regex]'"[^"]*"'
$rx.Replace($s, { param($m) $m.value.Replace(';','|') })
# => Camp;Brazil;AI;BCS GRU;;MIL-32011257;172-43333640;;"1975995|1972871|1975";FAC0088/21;3;20.000;24.8;25.000;.149;GLASSES SPARE PARTS,;EXW;C;.00;EUR;
也就是说,匹配两个"
字符之间的任何子字符串,并仅将所有;
字符替换|
为匹配项中的字符。
此外,这里是 PowerShell Core v6.1+ 版本,您可以在其中传递一个脚本块作为-replace
替换操作数,其中匹配表示为自动$_
变量:
(Get-Content $file.PSPath) |
Foreach-Object { $_ -replace '"[^"]*"', { $_.Value.Replace(';', '|') } }
为什么不使用环视?
由于左右分隔符是相同的单个字符, "
,因此任何基于环视的解决方案都将是错误的或太长并且仍然容易出错。之所以会发生这种情况,是因为环视不会消耗它们匹配的文本,"
因此每个文本都可以作为初始的"
. 看一下(?<="[^"]*);(?=[^"]*")
正则表达式,其中"b;c;d";1;23;"45;677777;z"
变成了,"b|c|d"|1|23|"45|677777|z"
因为;
在1
and23
和23
and"
之间找到了两个双引号。
类似的问题也存在于\G
基于 - 的模式上,该模式可用于匹配两个不同分隔符之间的多个匹配项,并且通常不用于 .NET 正则表达式,因为后者支持无限宽度的lookbehinds。
推荐阅读
- python - 在python中如何以一定的概率随机替换数组的特定元素?
- nestjs - 理解nestjs中的body装饰器
- wpf - 如何在 XAML 的堆栈面板中平衡几个文本框?
- flutter - 无法从 SqFLite 显示 ListView
- javascript - 在 React 中运行时停止功能
- python - 为什么我不能在图形视图上使用鼠标事件(mouseMoveEvent,mouseReleaseEvent)?
- web-scraping - 网页抓取返回空值
- html - 悬停时图像不会旋转
- swift - 如何在 SwiftUI 中将文本与屏幕顶部对齐
- getstream-io - 没有为 ID 为 XXX 的组织 XXXXXXXX 启用 getstream i get chat