PowerShell正则表达式(十一)使用反向引用


最后一个例子在一个字符串中替换了多个指定的关键字。通常效率还是挺高的,但是有时候你可能不想替换所有出现的关键字,而只是想替换出现在特殊上下文中的关键字。这样的情况下,上下文必须定义在模式中。例如,怎样更改正则表达式,让它只替换名字Miller和Meyer.

"Mr. Miller, Mrs. Meyer and Mr. Werner" -replace  
"(Mr.|Mrs.)\s*(Miller|Meyer)", "Our client"
# Our client, Our client and Mr. Werner

输出结果看起来有点奇怪,但是确实是和搜索模式匹配的。被替换掉的仅仅是Mr.或者Mrs. Miller和Mr. 或者 Mrs. Meyer。词语”Mr. Werner”没有被替换。遗憾的是结果没道理替换掉整个模式,至少人名应当保留。这可能吗?
此时反向引用应当登场了。在正则表达式中,不论你什么时候使用圆括号,圆括号中的结果都是分开被评估的。你可以在你的“替换串”中使用这些分离出来的结果。第一个子表达式的结果总是”Mr.” 或者a “Mrs.”。第二个子表达式总是返回人名。词语”$1” 和 “$2″在“替换串”中提供了你的子表达式(因此,数字是一串连续的数字;对于补充的子表达式你可以使用”$3″)。

"Mr. Miller, Mrs. Meyer and Mr. Werner" -replace "(Mr.|Mrs.)\s*(Miller|Meyer)", "Our client $2"
# Our client , Our client and Mr. Werner

奇怪的是,第一个反向引用似乎并没有工作。当然原因也非常明显: “$1” and “$2″看起来是PowerShell 变量, 但是实际上它们应当是操作符-replace的正则表达式词语。导致此结果的是你把“替换串”放在了双引号中了,PowerShell会将变量替换成具体的值,而这个值一般情况下应当为空。所以要是反向引用在“替换串”中起作用,你必须将“替换串”放置在单引号中,这样让$变成普通字符,这样PowerShell就不会把它识别为自己的变量了,并完成替换功能:

# 替换串文本必须放置单引号中,反向引用才能工作,
# $2才会替换成子表达式返回的值
"Mr. Miller, Mrs. Meyer and Mr. Werner" -replace "(Mr.|Mrs.)\s*(Miller|Meyer)", 'Our client $2'
# Our client Miller, Our client Meyer and Mr. Werner

# 另外也可以使用转义字符 `$来标记$:
"Mr. Miller, Mrs. Meyer and Mr. Werner" -replace "(Mr.|Mrs.)\s*(Miller|Meyer)", "Our client `$2"
# Our client Miller, Our client Meyer and Mr. Werner
本文链接: https://www.pstips.net/regex-back-reference.html
请尊重原作者和编辑的辛勤劳动,欢迎转载,并注明出处!

关于 Mooser Lee

我是一个Powershell的爱好者,创建了PowerShell中文博客,热衷于Powershell技术的搜集和分享。本站部分内容来源于互联网,不足之处敬请谅解,并欢迎您批评指正。

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注