使用 Powershell 替换正则表达式结果的小节 [英] Use Powershell to replace subsection of regex result

查看:36
本文介绍了使用 Powershell 替换正则表达式结果的小节的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 Powershell,我知道如何使用正则表达式在文件中搜索复杂的字符串,并将其替换为某个固定值,如以下代码段所示:

Using Powershell, I know how to search a file for a complicated string using a regex, and replace that with some fixed value, as in the following snippet:

Get-ChildItem  "*.txt" |
Foreach-Object {
    $c = ($_ | Get-Content)
    $c = $c -replace $regexA,'NewText'
    [IO.File]::WriteAllText($_.FullName, ($c -join "`r`n"))
}

现在我想弄清楚如何替换正则表达式每个匹配项的小节.这可以像上面一样通过一个平滑的步骤完成吗?或者您是否必须提取较大正则表达式的每个匹配项,在其中搜索和替换,然后以某种方式将该结果粘贴回原始文本?

Now I'm trying to figure out how to replace a subsection of each match of a regex. Can this be done in one smooth step like above? Or do you have to extract each match of the larger regex, search and replace within it, and then somehow stick that result back into the original text?

为了澄清一个例子,假设在下面的测试文本中,我只想在下面的文本中找到编号为 14xx 的实例,例如TEST=*1404",并将 14xx 替换为 16xx?

To clarify with an example, suppose that in the following test text I want to find only the 14xx-numbered instances like "TEST=*1404" in the following text, and replace the 14xx with 16xx?

A 2180 1830 12 0 3 3 TEST=C1404
A 900 1830 12 0 3 3 TEST=R1413
A 400 1830 12 0 3 3 TEST=R1411
A 1090 1970 12 0 3 3 TEST=U1400
A 1090 1970 12 0 3 3 TEST=CSA1400
A 1090 1970 12 0 3 3 TEST=CSA1414
A 1090 1970 12 0 3 3 TEST=CSA140
A 1090 1970 12 0 3 3 TEST=CSA14001
A 1090 1970 12 0 3 3 TEST=CSA17001

即我希望生成的文本如下所示,您会注意到只有前 6 行应该更改:

I.e. I'd like the resulting text to be as follows, where you'll note that only the first 6 lines should change:

A 2180 1830 12 0 3 3 TEST=C1604
A 900 1830 12 0 3 3 TEST=R1613
A 400 1830 12 0 3 3 TEST=R1611
A 1090 1970 12 0 3 3 TEST=U1600
A 1090 1970 12 0 3 3 TEST=CSA1600
A 1090 1970 12 0 3 3 TEST=CSA1614 <- Second instance of '14' shouldn't change
A 1090 1970 12 0 3 3 TEST=CSA140 <- Shorter numbers shouldn't change
A 1090 1970 12 0 3 3 TEST=CSA14001 <- Longer numbers shouldn't change
A 1090 1970 12 0 3 3 TEST=CSA17001

以下正则表达式似乎可以找到需要替换的较大字符串,但我不知道 Powershell (replace?) 中的哪些功能用于替换结果的子串.另外,如果有帮助,请随时提出更好的正则表达式.

The following regex seems to do the job of finding the larger strings where I need to make replacements, but I don't know what functionality in Powershell (replace?) to use to just replace the substring of the results. Also, feel free to suggest a better regex if that would help.

$regexA = "\bTEST=\b[A-Za-z]+14\d\d\r"

我宁愿不必硬编码一个详尽的列表,列出可以位于="和数字之间的内容,例如R"、C"、CSA"等.

I'd rather not have to hard-code an exhaustive list of the stuff that can come between the '=' and the numbers, like 'R', 'C', "CSA", etc.

我已经做了一个小时左右的工作,在那里我获得了正则表达式的所有匹配项,在其中搜索以将 14 替换为 16,然后使用旧值和新值对原始文本运行替换,例如replace($myText,"TEST=CSA1400","TEST=CSA1600"),但这并没有很好地掩盖特殊情况,感觉就像我在走下坡路.

I've been working on something for an hour or so where I get all the matches for the regex, search within them to replace 14 with 16, then run replace on the original text with the old and new values, e.g. replace($myText,"TEST=CSA1400","TEST=CSA1600"), but this is not covering off the special cases very well, and it feels like I'm heading down the rabbit-hole.

推荐答案

您需要对要保留的子表达式进行分组(即,将它们放在括号之间),然后通过变量 $1$2 在替换字符串中.尝试这样的事情:

You need to group the sub-expressions you want to preserve (i.e. put them between parentheses) and then reference the groups via the variables $1 and $2 in the replacement string. Try something like this:

$regexA = '( TEST=[A-Za-z]+)14(\d\d)$'

Get-ChildItem '*.txt' | ForEach-Object {
    $c = (Get-Content $_.FullName) -replace $regexA, '${1}16$2' -join "`r`n"
    [IO.File]::WriteAllText($_.FullName, $c)
}

这篇关于使用 Powershell 替换正则表达式结果的小节的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆