如何改变反向引用的案例?

时间:2011-07-25 15:50:49

标签: regex powershell

我正在尝试修改PowerShell中的后向引用,但我没有运气:(

这是我的例子:

"456,Jane Doe" -replace '^(\d{3}),(.*)$',"| $(`"`$2`".ToUpper()) | `$1 |"

如果我运行它,我会得到这个:

| Jane Doe | 456 |

但我真的很期待这个:

| JANE DOE | 456 |

如果我运行以下命令(与上面相同,但在调用ToUpper时没有'()'):

"456,Jane Doe" -replace '^(\d{3}),(.*)$',"| $(`"`$2`".ToUpper) | `$1 |"

我明白了:

| string ToUpper(), string ToUpper(System.Globalization.CultureInfo culture) | 456 |

所以看起来PowerShell知道后面的引用'$ 2'是一个字符串,但为什么我不能让PowerShell将它转换为大写?

特里

2 个答案:

答案 0 :(得分:3)

[Regex]::Replace('456,Jane Doe',
    '^(\d{3}),(.*)$',
    {
        param($m)
        '| ' + $m.Groups[2].Value.ToUpper() + ' | ' + $m.Groups[1].Value + ' |'
    }
)

不是很漂亮,我承认。遗憾的是,您无法在-replace运算符中使用脚本块作为替换。

答案 1 :(得分:0)

只是为了解释发生了什么,在"| $(`"`$2`".ToUpper()) | `$1 |"中,PowerShell在将字符串传递给-replace运算符之前评估突出显示的子表达式,而不是在发生替换操作之后

换句话说,在字符串值$2上调用ToUpper,导致| $2 | $1 |用于替换操作。您可以通过在子表达式字符串中包含一个字母来查看此内容,例如:

"456,Jane Doe" -replace '^(\d{3}),(.*)$',"| $(`"zz `$2`".ToUpper()) | `$1 |"

这有一个有效的| ZZ $2 | $1 |替换字符串,结果为| ZZ Jane Doe | 456 |


类似地,省略括号"| $(`"`$2`".ToUpper) | `$1 |"的第二个版本被评估为"some string".ToUpper,它将ToUpper方法的重载数组放在替换字符串中System.String。< / p>


要将替换操作保持为单行,Joey's answer使用the MatchEvaluator overload to Regex.Replace效果很好。或者您可以根据-match

的结果自行进行字符串格式设置
if( '456,Jane Doe' -match '^(\d{3}),(.*)$' ) {
  '| {0} | {1} |' -f $matches[2].ToUpper(),$matches[1]
}

如果需要在较大字符串的上下文中替换它,则可以始终进行文字替换以获得最终结果:

PS> $r = '| {0} | {1} |' -f $matches[2].ToUpper(),$matches[1]
PS> 'A longer string with 456,Jane Doe in it.'.Replace( $matches[0], $r )
A longer string with | JANE DOE | 456 | in it.