假设我有两个地址:
- 123 Newark Road Ne
- 尼荷兰大街987号
我需要将方向部分从Ne更新到Ne。但是,我不想将Newark更新到Newark,荷兰也是如此。我想我可以用这个循环中的IF语句找到所有的例子:
$testAddress = '123 Newark Road Ne'
if (($testAddress -clike '* Ne') -or ($testAddress -clike '* Ne *')){
#code to replace Ne
}
但是我该如何更换它呢?我不能用"*Ne","*Ne"。找到'*Ne'的索引只会给我-1,所以我认为我对此无能为力。我相信有一个简单的概念,我只是没有遇到。
您可以使用正则表达式,通过使用MatchEvaluator
(它在PowerShell中像脚本块一样构造(,将输入的某个部分替换为regex表达式中的替换操作数中设计不可能的部分(如.NET中的大写(。
有了MatchEvaluator,您可以随心所欲地操纵匹配的零件,因此在操纵方面不受任何限制。
从PowerShell 6开始,您甚至可以直接将其与-replace
和-creplace
运算符一起使用
6以下的PowerShell版本没有此选项,但仍然可以使用带有MatchEvaluator的.NET Regex替换方法[regex]::Replace()
。
PS 5.1
$textToReplace = 'Ne 123 Newark Road Ne', '123 Newark Road Ne', '987 Ne Netherland Avenue'
foreach ($text in $textToReplace) {
# using a scriptblock as System.Text.RegularExpressions.MatchEvaluator
# the param() part is mandatory. Everything that follows is the return for that particular match
[regex]::Replace($text, '(?<!w)Ne(?!w)', { param($regexMatch) $regexMatch.Value.ToUpper() })
}
第6页+
$textToReplace = 'Ne 123 Newark Road Ne', '123 Newark Road Ne', '987 Ne Netherland Avenue'
foreach ($text in $textToReplace) {
$text -creplace '(?<!w)Ne(?!w)', { $_.Value.toUpper() }
}
正则表达式模式解释
模式(?<!w)Ne(?!w)
使用negative lookbehind (?<!)
和negative lookahead (?!)
组构造来匹配前一个和后一个字符不是字字符的所有字Ne
。
.NET
中的w
(Word(包括以下类别的所有Unicode字符:
MSFT:正则表达式中的字符类->单词字符:\w:
这些包括但不限于:
a-z
和类似è
的变体A-Z
和类似À
的变体0-9
_
- 西里尔字母
- 汉字
简而言之,w
捕获几乎Unicode字符集中表示的所有单词字符。
资源
MSFT:在PS6+中用脚本块替换
@('123 Newark Road Ne'
'987 Ne Netherland Avenue')|foreach{
switch -regex ($_)
{
'Ne$'{$_ -replace 'Ne$','NE'}
' Ne '{$_ -replace ' Ne ',' NE '}
Default {$_}
}
}
或者在Ne
:周围使用单词边界
'123 Newark Road Ne','987 Ne Netherland Avenue' | ForEach-Object {
if ($_ -cmatch '(bNeb)') { $_ -creplace '(bNeb)', $Matches[1].ToUpper() }
else { $_ }
}
输出
123 Newark Road NE
987 NE Netherland Avenue