Powershell заменить между началом и концом - PullRequest
0 голосов
/ 03 января 2019

Мне нужно заменить все между двумя точками.

$import = Get-Content C:\bookmarks.html
$newbody = Get-Content C:\newbookmarks.html
$remove = '(?<=<DT><H3 ADD_DATE=""1544626193"" LAST_MODIFIED=""154649885"">Import-IE</H3>).*?(?=</DL>)'
$import | %{$_.replace($remove,"$newbody")}

Моя проблема - получить весь контент между началом:

<DT><H3 ADD_DATE=""1544626193"" LAST_MODIFIED=""154649885"">Import-IE</H3>

и концом:

</DL>

включая несколько строк

Пример html:

<DT><H3 ADD_DATE="1544626193" LAST_MODIFIED="1546498855">Import-IE</H3>  
<DL><p>
<DT><A HREF=https://www.golem.de/ ADD_DATE="1544626193" LAST_MODIFIED="1546498842">golem.de</A>
<DT><A HREF=https://www.heise.de/ ADD_DATE="1544626193" LAST_MODIFIED="1546498842">heise online</A>
</DL>

С уважением

1 Ответ

0 голосов
/ 03 января 2019

Пара изменений, необходимых для этой работы:

Одна большая многострочная строка

Поскольку вы хотите выполнить замену нескольких строк, мы должны убедиться, что все строки содержатсяв той же строке, так что давайте начнем с этого - мы можем использовать параметр параметра -Raw с Get-Content:

$import = Get-Content C:\bookmarks.html -Raw

Точное сопоставление с шаблоном в регулярном выражении

Далее мы имеемсам шаблон регулярного выражения - между этим и примером содержимого, которое вы показали, есть несколько расхождений:

LAST_MODIFIED=""154649885"" # pattern has nested double-quotes and only one 5 at the end
LAST_MODIFIED="1546498855"  # input uses just one pair of double-quotes and value has two 5's at the end

Итак, давайте исправим это и убедимся, что искомая входная строка правильно экранирована, пока мы 'на это:

$remove = "(?<=$([regex]::Escape('<DT><H3 ADD_DATE="1544626193" LAST_MODIFIED="1546498855">Import-IE</H3>'))).*?(?=</DL>)"

String.Replace не поддерживает регулярное выражение

Затем нам придется отказаться от метода String.Replace(), который вы используете в настоящее время - потому что он нена самом деле не поддерживает регулярные выражения - поэтому вместо этого мы будем использовать оператор -replace:

$import -replace $remove,"$newbody"

Использовать -replace в режиме SingleLine

Единственное, что нам сейчас нужно, это инструктироватьанализатор регулярных выражений для обработки ввода в режиме SingleLine - sо, что .*? будет также захватывать новые строки.Это очень просто, мы просто добавляем флаг опций s в начале шаблона регулярного выражения:

$import -replace "(?s)$remove","$newbody"

И это все :)

$import = Get-Content C:\bookmarks.html -Raw
$newbody = Get-Content C:\newbookmarks.html
$remove = "(?<=$([regex]::Escape('<DT><H3 ADD_DATE="1544626193" LAST_MODIFIED="1546498855">Import-IE</H3>'))).*?(?=</DL>)"
$import -replace "(?s)$remove","$newbody"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...