#regex
Вопрос:
Вопрос
Я пытаюсь сопоставить тире-комментарии PowerShell ( # ...
), но не встроенные комментарии ( <# .. #>
) в одном и том же регулярном выражении. Как я могу этого достичь?
Цель
Матч
Я хотел бы сопоставить комментарии PowerShell (используя синтаксис комментариев с хэштегами). Так что просто все, что после #
, закомментировано. Я использую #(.*$)/gm
для этого.
Тестовые примеры, в которых соответствие регулярному выражению записывается в скобках [..]
:
Write-Host "Hello world" [# comment here]
[# A line with only comment]
Comment without whitespace[#before]
[Comment with whitespace [#after ]
Не совпадают
Однако то, что я хотел бы использовать здесь, — это исключение для «синтаксиса встроенных комментариев». Встроенные комментарии в PowerShell выглядят так lorem <# inline comment #> ipsus
.
Поэтому здесь я ищу исключения для:
Write-Host "Hello world" <# inline comment here #>
<# A line with only inline comment #>
Comment without whitespace<#no whitespace#>around
Inline comment <# in middle #> of line
Comment with whitespace #comment with >
Comment with whitespace #comment with <
Comment with whitespace #comment with <# test #>
Что я пытался
Я пытался использовать [^<>]
для чего-то подобного #[^<>](.*[^<>]$)
, но это не сработало для всех случаев, приведенных выше.
Мой прогресс в регулярном выражении 101, пока я не застрял.
Почему?
Я анализирую PowerShell в среде выполнения JavaScript/TypeScript, чтобы иметь возможность встроить их для пакетного запуска ( cmd
) для проекта с открытым исходным кодом, управляемого сообществом. Я знаю, что из этого будут исключения (например, строки с тире внутри), но я отказываюсь от простого анализа регулярных выражений для надежности.
Спасибо!
Ответ №1:
Я предлагаю проверить <
перед #
символом и преобразовать все отрицательные классы символов в отрицательные, чтобы избежать пересечения границ строк:
#(?<!<#)(?![<>])(.*)$(?<![<>])
// Or, to also check for #> after <# use
#(?<!<#(?=.*#>))(?![<>])(.*)$(?<![<>])
Смотрите демонстрацию регулярных выражений. Удалите (?<![<>])
отрицательный внешний вид, если вы не хотите пропустить совпадение, если строка заканчивается на <
или >
.
Подробные сведения:
#
— а#
чар(?<!<#)
— не<#
разрешено сразу слева от текущего местоположения (обратите внимание , что эта проверка запускается только после#
, чтобы механизм регулярных выражений мог проверять только позиции после#
, а не каждую позицию в строке ((?<!<#(?=.*#>))
lookbehind с вложенным заголовком гарантирует#
, что совпадение не является вторым символом<#...#>
подстроки)(?![<>])
— сразу справа, там не должно быть<
и>
(.*)
— Группа 1: любые нулевые или более символов, кроме символов разрыва строки, как можно больше$
— конец строки(?<![<>])
— в конце строки не должно быть<
и>
символов.
Комментарии:
1. Я только что понял, что это не удается при использовании одного
<
или>
в тире комментария. НапримерComment with whitespace #comment with >
,,Comment with whitespace #comment with <
,.# Comment with <# test #>
Можно ли было бы также сопоставить их?2.@U. Булле вы имеете в виду , что если они заканчиваются на
<
или>
, они должны быть сопоставлены? Затем удалите последний взгляд назад. Посмотрите эту демонстрацию. Кроме того, если вам также нужно проверить наличие#>
«после<#
«, вы можете использовать#(?<!<#(?=.*#>))(?![<>])(.*)$