Последовательность совпадения с регулярным выражением Powershell не работает, хотя она совпадает в Sublime Text, найдите и замените - PullRequest
0 голосов
/ 18 февраля 2019

Я пытаюсь создать оператор регулярного выражения Powershell, чтобы удалить первые пять строк этого вывода из файла git diff, который уже был изменен с помощью регулярного выражения Powershell.

[1mdiff --git a/uk1.adoc b/uk2.adoc</span>+++
[1mindex b5d3bf7..90299b8 100644</span>+++
[1m--- a/uk1.adoc</span>+++
[1m+++ b/uk2.adoc</span>+++
[36m@@ -1,9 +1,9 @@</span>+++
= Heading

Body text

Image shown because binary code doesn't show in the text

Изображение показано потому, что двоичный код не отображается в тексте

Следующее выражение соответствует тексту, поэтомуСтрока '= Заголовок' помещается вверху страницы, если я заменяю ее ничем.

^[^=]*.[+][\n]

enter image description here

Но в Powershell это не такне соответствует тексту.

Get-Content "result2.adoc" | % { $_  -Replace '^[^=]*.[+][\n]', '' } | Out-File  "result3.adoc";

enter image description here

Есть идеи о том, почему это не работает в Powershell?

Моя общая цельсоздать файл diff из двух версий файла AsciiDoc, а затем заменить коды ASCII на код HTML / CSS, чтобы отобразить полученный файл AsciiDoc с изменениями дорожек зеленого / красного цвета.

Ответы [ 2 ]

0 голосов
/ 19 февраля 2019

Вот код, который я получил после помощи @ mklement0.Этот скрипт Powershell создает изменения трека в стиле MS Word для двух версий файла AsciiDoc.Он создает файл Diff, использует регулярные выражения для замены кодов ASCII тегами HTML / CSS, удаляет заголовок Diff (спасибо!), Использует AsciiDoctor для создания файла HTML, а затем PrinceXML для создания PDF-файла вывода, который я могу отправитьдля рецензентов документов.

    git diff --color-words file1.adoc file2.adoc > result.adoc;
Get-Content "result.adoc" | % {
$_  -Replace '(=+ ?)([A-Za-z\s]+)(\[m)', '$1$2' `
    -Replace '\[32m', '+++<span style="color: #00cd00;">' `
    -Replace '\[31m', '+++<span style="color: #cd0000; text-decoration: line-through;">' `
    -Replace '\[m', '</span>+++' } | Out-File -encoding utf8 "result2.adoc" ;
(Get-Content -Raw result2.adoc) -replace '(?s)^.+?\n(?==)', '' | Out-File -encoding utf8 "result3.adoc" ;
asciidoctor result3.adoc -o result3.html;
prince result3.html --javascript -o result3.pdf;
Read-Host -Prompt "Press Enter to exit"

Вот скриншот результата с использованием некоторого текста из Википедии:

enter image description here

0 голосов
/ 19 февраля 2019

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

(Get-Content -Raw result2.adoc) -replace '(?s)^.+?\n(?==)' |
  Set-Content result3.adoc
  • (?s) активирует встроенную опцию s, которая позволяет . соответствовать символам новой строки (\n).

  • ^.+?\n(?==) соответствует от начала строки (^) любому количеству символов (включая символы новой строки) (.+), без жадности (?)

  • донайден символ новой строки (\n), за которым следует =.

    • (?=...) - это прогнозное утверждение, которое соответствует = без потребления it, т.е., не считая ее частью подстроки, которая соответствует.

Поскольку операнд-заменитель не передается в -replace, все совпадение заменяется подразумеваемой пустой строкой , то есть то, что было сопоставлено, фактически удалено .


Что касается того, что вы пытались :

Оператор -replace передает свой LHS через , если совпадений не найдено, поэтому вы не можете использовать его для отфильтровывания несоответствующих строк.

Даже если вы соответствуетенежелательную строку полностью и замените ее на '' (пустая строка), она будет отображаться как пустая строка в выводе при отправке на Set-Content или Out-File (>).

Что касается вашего конкретного регулярного выражения, ^[^=]*.[+][\n] (независимо от того, следует ли за первым ^ символ ESC (0x1b).):

  • [\n] (достаточно \n) пытается найти символ новой строки.после литерала + ([+]), но строки, считываемые индивидуально с Get-Content (без -Raw) по определению, равняются лишенным их завершающей строки, поэтому \n никогда не будет совпадать;вместо этого используйте $, чтобы соответствовать концу строки.

Вместо % (встроенный псевдоним для командлета ForEach-Object), который вы могли бы использовать ? (встроенный псевдоним для командлета Where-Object) для выполнения требуемой фильтрации:

Get-Content result2.adoc | ? { $_ -notmatch '^\e\[' }

$_ -notmatch '^\e[' возвращает $True только для строк, которые не начинаются (^) ссимвол ESC (\e, кодовая точка которого 0x1b), за которым следует литерал (\) [, тем самым эффективно отфильтровывая строки перед строкой = Heading.

Однако,многострочная команда -replace вверху является более прямым и быстрым выражением вашего намерения.

...