我对PowerShell的-replace
运算符在使用正则表达式时的工作方式感到困惑。我在线查找文档,但找不到比基本用法更详细的内容:它查找字符串,并用另一个字符串(如果已定义)或任何内容替换该字符串。大。
我希望与this question中的用户想要从复杂字符串中提取简单程序名称的人做同样的事情。这是我试图复制的代码:
$string = '% O0033(SUB RAD MSD 50R III) G91G1X-6.4Z-2.F500 G3I6.4Z-8.G3I6.4 G3R3.2X6.4F500 G91G0Z5. G91G1X-10.4 G3I10.4 G3R5.2X10.4 G90G0Z2. M99 %'
$program = $string -replace '^%\sO\d{4}\((.+?)\).+$','$1'
$program
SUB RAD MSD 50R III
正如您所看到的,输出字符串是用户想要的字符串,其他所有字符串都被过滤掉了。对我来说,唯一的区别是我想要一个由六位数字组成的字符串,而不是别的。但是,当我尝试使用我的正则表达式对字符串执行此操作时,我得到了这个:
$string2 = '1_123456_1'
$program2 = $string -replace '(\d{6})','$1'
$program2
1_123456_1
没有变化。为什么会这样?我的代码应该是什么?此外,代码中使用的$1
是什么?
答案 0 :(得分:5)
-replace
运算符仅替换匹配的字符串部分。捕获组匹配匹配的某个子集(或所有匹配),并且您可以在替换字符串中引用捕获组。
您的第二个示例仅匹配您要提取的部分。因此,您需要确保匹配整个字符串,但只有捕获您要保留的部分,然后使替换字符串与您的捕获匹配:
$string2 = '1_123456_1'
$program2 = $string -replace '\d_(\d{6})_\d','$1'
$program2
你如何匹配"字符串的其余部分"你决定;这取决于它可能包含的内容。所以我上面所做的只是一种可能的方式。其他可能的模式:
1_(\d{6})_1
[^_]*_(\d{6})_[^_]*
^.*?(\d{6}).*?$
答案 1 :(得分:5)
捕获组(未转义的括号对)用于轻松访问匹配的部分内容。在字符串上使用-replace
时,匹配所有非重叠的子字符串,并替换/删除这些子字符串。
在您的情况下,-replace '(\d{6})', '$1'
表示替换整个匹配(等于第一次捕获,因为您将整个模式与捕获组一起包含)与其自身强>
当你想要获得字符串的一部分时,在像你这样的情况下使用-match
:
PS> $string2 = '1_123456_1'
PS> $string2 -match '[0-9]{6}'
PS> $Matches[0]
123456
-match
将为您提供第一场比赛,正是您想要的。
当需要修改字符串(重新格式化字符串,插入/删除字符等)时,请使用-replace
。