如何使用PowerShell解析XML文件并在两个标记之间删除文本?

Mik*_*e J 1 regex powershell replace find

我有一个文件,其中包含以下多个实例:

<password encrypted="True">271NFANCMnd8BFdERjHoAwEA7BTuX</password>
Run Code Online (Sandbox Code Playgroud)

但是对于每个实例,密码都是不同的.

我想输出删除encyrpted密码:

<password encrypted="True"></password>
Run Code Online (Sandbox Code Playgroud)

使用PowerShell循环遍历文件中所有模式实例并输出到新文件的最佳方法是什么?

就像是:

gc file1.txt | (regex here) > new_file.txt
Run Code Online (Sandbox Code Playgroud)

其中(正则表达式)是这样的:

s/"True">.*<\/pass//
Run Code Online (Sandbox Code Playgroud)

bri*_*ist 5

这个在正则表达式中相当容易,你可以这样做,或者你可以将它解析为实际的XML,这可能更合适.我将展示两种方式.在每种情况下,我们将从这个常见位开始:

$raw = @"
<xml>
    <something>
        <password encrypted="True">hudhisd8sd9866786863rt</password>
    </something>
    <another>
        <thing>
            <password encrypted="True">nhhs77378hd8y3y8y282yr892</password>
        </thing>
    </another>
    <test>
        <password encrypted="False">plain password here</password>
    </test>
</xml>
"@
Run Code Online (Sandbox Code Playgroud)

正则表达式

$raw -ireplace '(<password encrypted="True">)[^<]+(</password>)', '$1$2'
Run Code Online (Sandbox Code Playgroud)

要么:

$raw -ireplace '(?<=<password encrypted="True">).+?(?=</password>)', ''
Run Code Online (Sandbox Code Playgroud)

XML

$xml = [xml]$raw

foreach($password in $xml.SelectNodes('//password')) {
    $password.InnerText = ''
}
Run Code Online (Sandbox Code Playgroud)

仅替换加密密码:

$xml = [xml]$raw

foreach($password in $xml.SelectNodes('//password[@encrypted="True"]')) {
    $password.InnerText = ''
}
Run Code Online (Sandbox Code Playgroud)

说明

正则表达式1

(<password encrypted="True">)[^<]+(</password>)
Run Code Online (Sandbox Code Playgroud)

正则表达式可视化

Debuggex演示

第一个正则表达式方法使用2个捕获组来捕获开始和结束标记,并用这些标记替换整个匹配(因此中间省略).

正则表达式2

(?<=<password encrypted="True">).+?(?=</password>)
Run Code Online (Sandbox Code Playgroud)

正则表达式可视化

Debuggex演示

第二种正则表达式方法使用正向前瞻和后观.它找到1个或多个前面有开始标记并后跟结束标记的字符.由于lookarounds是零宽度,它们不是匹配的一部分,因此它们不会被替换.

XML

这里我们使用一个简单的xpath查询来查找所有password节点.我们用循环遍历每个foreach循环并将其设置innerText为空字符串.

第二个版本检查加密属性是否设置为True仅对其进行操作.

选择哪个

我个人认为XML方法更合适,因为这意味着您不必非常考虑XML语法的变化.您还可以更轻松地考虑节点上指定的不同属性或不同的属性值.

通过使用xpath,您可以比使用正则表达式处理XML更具灵活性.

文件操作

我注意到你的样本读取了所用的数据gc(简称Get-Content).请注意,这会逐行读取文件.

您可以使用它来将原始内容放在一个字符串中,以便转换为XML或通过正则表达式进行处理:

$raw = Get-Content file1.txt -Raw
Run Code Online (Sandbox Code Playgroud)

你也可以很容易地写出来:

$raw | Out-File file1.txt
Run Code Online (Sandbox Code Playgroud)