2

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

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

4

5 回答 5

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
于 2018-11-10T18:22:43.003 回答
1

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

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

(Get-Content $original_file) -replace "(<span>)+(</span>)+" | 
 Set-Content $destination_file
于 2018-11-11T13:12:48.993 回答
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>

于 2018-11-10T18:19:26.863 回答
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 
}
于 2018-11-10T18:24:11.223 回答
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]
于 2018-11-11T00:13:20.487 回答