使用PowerShell循环搜索并在文件上替换两部分字符串,同时保留其中一部分

时间:2018-11-10 17:41:11

标签: regex powershell

我是PowerShell的新手,但没有找到堆栈溢出问题或文档参考,无法使我一直获得成功。如果已经有一个问题或文档参考文献回答了我忽略的问题,我将不胜感激。

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

<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发布管道中包含的脚本。

感谢任何想法或帮助。

5 个答案:

答案 0 :(得分:1)

请尝试以下操作。.我添加了一些注释以澄清问题。

# 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

答案 1 :(得分:1)

如果您只想删除任意数量的空跨度,请使用带有组和量词的正则表达式:

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

(Get-Content $original_file) -replace "(<span>)+(</span>)+" | 
 Set-Content $destination_file

答案 2 :(得分:0)

您可以将正则表达式与-replace运算符一起使用,以从字符串中去除所有<span>optional content</span>对。这意味着开始标记未指定任何属性的所有对。

$content = '<span></span><span><span><span style="font-weight:bold;">Foo</span></span></span>'
$regex = '<span>(.*?)</span>'    
while ($content -match $regex)
{
    $content = $content -replace $regex,'$1'
}
Write-Output $content

结果将是:

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

while循环会处理<span></span>对的嵌套出现。

答案 3 :(得分:0)

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

ForEach ($Line in (Get-Content $original_file)) {
    Do {
        $Line = $Line -replace '<span></span>',''
    } While ($Line -match '<span></span>')
    Set-Content -Path $destination_file -Value $Line 
}

答案 4 :(得分:0)

$content = '<span></span><span><span><span style="font-weight:bold;">Foo</span></span></span>'
$regex = '<span\s+[^<]+</span>'
$null = $content -match $regex

$Matches[0]