Регулярное выражение для правила «не может иметь этот символ до и после»

#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. Булле вы имеете в виду , что если они заканчиваются на < или > , они должны быть сопоставлены? Затем удалите последний взгляд назад. Посмотрите эту демонстрацию. Кроме того, если вам также нужно проверить наличие #> «после <# «, вы можете использовать #(?<!<#(?=.*#>))(?![<>])(.*)$