首页 > 解决方案 > 使用 PowerShell 在文件上循环搜索和替换两部分字符串,同时保留其中一个部分

问题描述

我是 PowerShell 的新手,还没有找到让我一路走来获得成功结果的 Stack Overflow 问题或文档参考。如果已经存在可以回答我忽略的问题或文档参考,我将不胜感激。

在文本文件中是这样的字符串:

<span><span><span><span><span></span></span></span></span></span>

文件的数量<span></span>数量因文件而异。例如,在某些文件中是这样的:

<span></span>

然而在其他人中是这样的:

<span><span></span></span>

等等。一个字符串中的每个可能永远不会超过 24 个。

我想在文本文件中消除所有这样的字符串,但保留这样</span>的字符串:

<span style="font-weight:bold;">text</span>

文本文件中的那种字符串可能有很多变体;例如,<span style="font-size: 10px; font-weight: 400;">text</span>或者<span style="font-size: 10px; font-weight: 400;">text</span>我事先不知道文本文件中将包含哪些变体。

这部分有效......

$original_file = 'in.txt'
$destination_file = 'out.txt'

(Get-Content $original_file) | Foreach-Object {
    $_ -replace '<span>', '' `
       -replace '</span>', ''
} | Set-Content $destination_file

...但显然会导致类似<span style="font-weight:bold;">text.

在上面的 PowerShell 脚本中,我可以使用

    $_ -replace '<span></span>', '' `

但当然它只捕获<span></span>字符串中间的 ,因为正如现在所写的那样,它不会循环。

我知道做这样的事情很愚蠢

$original_file = 'in.txt'
$destination_file = 'out.txt'

(Get-Content $original_file) | Foreach-Object {
    $_ -replace '<span></span>', '' `
       -replace '<span></span>', '' `
       -replace '<span></span>', '' `
       -replace '<span></span>', '' `
       -replace '<span></span>', '' 
} | Set-Content $destination_file

因此,因为<span>每次运行脚本时字符串都会自行折叠,从而产生一个新的内部<span></span>,然后可以将其删除,所以我能想到的最佳解决方案是在文件上循环脚本,直到它识别出所有实例<span></span>都消失了。

我觉得有必要在这些方面添加逻辑:

   foreach($i in 1..24){
    Write-Host $i

但是一直没能成功地将它合并到脚本中。

如果这完全是错误的方法,我将不胜感激。

使用 PowerShell 的原因是我的团队更喜欢它用于包含在 Azure DevOps 发布管道中的脚本。

感谢您的任何想法或帮助。

标签: regexpowershell

解决方案


试试下面的..我添加了一些评论来澄清事情。

# always use absolute paths if possible
$original_file = 'c:\tmp\in.txt'
$destination_file = 'c:\tmp\out.txt'

$patternToBeRemoved = '<span></span>'

# store the file contents in a variable
$fileContent = Get-Content -Path $original_file

# save the result of these operations in a new variable and iterate through each line
$newContent = foreach($string in $fileContent) {
    # while the pattern you don't want is found it will be removed
    while($string.Contains($patternToBeRemoved)) {
        $string = $string.Replace($patternToBeRemoved, '')
    }
    # when it's no longer found the new string is returned
    $string
}

# save the new content in the destination file
Set-Content -Path $destination_file -Value $newContent

推荐阅读