我在办公室继承了一个项目,但我似乎不太能找到答案。我正在尝试使用 Regex 编写一个 Powershell 脚本来替换多行逗号分隔的 CSV 文件的特定字段中的文本,但我要替换的文本可能存在于其他字段中。
例如以下数据中:
Smith,Robert,W,11111 N 400 W,Some City,Some State,Some Zip
我需要将第四列中的
W
替换为West
,但我不希望第三列(或其他列)中的W
被更改。至少,我可以让它搜索第 n 个逗号之后的任何匹配项,因为街道地址后面的字段大多是数字,但理想情况下,最好只搜索特定列,以防有匹配的文本未来在其他地方。
我发现了一些技巧和正则表达式脚本,似乎让我很接近,但我很难让它用 Notepad++ 进行测试。有些脚本正在搜索直到第 n 个逗号的所有内容,有些脚本似乎是从行尾向后搜索(这不起作用,因为存在带有逗号的文本字段)。到目前为止,我在 PowerShell 脚本中得到的最接近的是:
-replace('^(?:[^,]*\,){3}([^,]*)\bW\b', 'West')
但这会将
W
及其之前的所有内容替换为 West
。
很可能有更好的方法来做到这一点,但我在这方面花费的时间比我预期的要多。任何帮助将不胜感激!
相当简单。您尝试的正则表达式非常接近。
直到第四列中的
W
只需与West这是一个便携式解决方案。
@"(?m)^((?:[^,]*,){3}[^,]*?)\bW\b"
更换
$1West
https://regex101.com/r/zLlP7L/1
(?m)
^
( # (1 start)
(?: [^,]* , ){3}
[^,]*?
) # (1 end)
\b W \b
使用记事本++:
^(?:[^,]*\,){3}[^,]*?\KW
West
说明:
^ # beginning of line
(?: # non capture group
[^,]* # 0 or more any character that is not a comma
, # a comma
){3} # end group, must appear 3 times
[^,]*? # 0 or more any character that is not a comma, not greedy
\K # forget all we have seen until this position
W # letter W
截图(之前):
截图(之后):
您可以使用lookbehind进行断言而不匹配这些内容(请注意,
,
不需要转义):
(?m) # (使 '^' 表示一行的开始) (?<= # Match 某事之前是 ^(?:[^,]*,){3} # 行首 3 列 [^,]* # 然后 0 个或多个非逗号字符, ) # 其中“something”的意思是 W # 没有相邻单词字符的“W”。
假设
$string
是您的输入,这是一个简短的 Powershell 片段:
(免责声明:我不太了解 Powershell。)
$result = $string -replace '(?m)(?<=^(?:[^,]*,){3}[^,]*)\bW\b', 'West'
请注意,Powershell 具有用于解析 CSV 文件的“内置支持”。您可能想使用它来避免任何潜在的问题。 在 tio.run 上尝试一下
。-replace('^([^,]*),([^,]*),([^,]*),([^,]*)\bW\b,', '\1,\2,\3,\4West,')
虽然我不确定正则表达式在powershell中如何工作,但有时你应该使用
$1
,$2
,...甚至
%1
,%2
,...但我相信\1
,\2
,... 最常见。解释/细分:
^
([^,]*)
匹配任何不是逗号的内容。这将是我们的第一个捕获组,\1
,
匹配文字逗号([^,]*),([^,]*),
另外两个不带逗号的捕获组,用于 \2
\3
。([^,]*)\bW\b,
匹配捕获组中不带逗号的内容 \4
W
,然后是逗号。
替换为:
\1,\2,\3,\4West