Я новичок в 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.
Спасибо за любые идеи или помощь.
🤔 А знаете ли вы, что...
PowerShell предоставляет инструменты для мониторинга производительности системы и приложений.
Вы можете использовать регулярное выражение вместе с оператором -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>
.
Попробуйте следующее ... Я добавил несколько комментариев, чтобы прояснить ситуацию.
# 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
$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
}
$content = '<span></span><span><span><span style = "font-weight:bold;">Foo</span></span></span>'
$regex = '<span\s+[^<]+</span>'
$null = $content -match $regex
$Matches[0]
Если вы просто хотите удалить любое количество пустых промежутков, используйте регулярное выражение с группой и квантификатором:
$original_file = 'in.txt'
$destination_file = 'out.txt'
(Get-Content $original_file) -replace "(<span>)+(</span>)+" |
Set-Content $destination_file