Нужно регулярное выражение, где две разные подстроки не должны быть включены в строку - PullRequest
1 голос
/ 12 марта 2019

У меня есть следующие строки:

$string = @(
  'Get-WindowsDevel'
  'Put-WindowsDevel'
  'Get-LinuxDevel'
  'Put-LinuxDevel'
)

Теперь мне нужно одно регулярное выражение со следующими двумя правилами:

  1. $string не должен начинаться с "Get -"
  2. $string не должен содержать «Linux»

Это исключает "Get-" в начале:

PS C:\> $string | Where-Object { $_ -match "^(?!Get-).*" }

Put-WindowsDevel
Put-LinuxDevel

Я ожидаю, что следующая команда не соответствует «Put-LinuxDevel», но она соответствует:

PS C:\> $string | Where-Object { $_ -match "^(?!Get-).*(?!Linux)" }

Put-WindowsDevel
Put-LinuxDevel

Итак, мне нужно регулярное выражение, действительное только для этой строки:

Пут-WindowsDevel

Ответы [ 2 ]

0 голосов
/ 13 марта 2019

Используйте -notmatch (или, если требуется регистр * необходимо сопоставление, -cnotmatch) - т. Е. a отрицание сопоставление - в сочетании с чередованием (|):

PS> $string -notmatch '(^Get-|Linux)'
Put-WindowsDevel
  • Оператор -match и его вариации (а также многие другие операторы) могут напрямую воздействовать на массивы как LHS, и в этом случае оператор действует как фильтр и возвращает только совпадающие элементы.

    • Использование -match в массиве намного быстрее, чем использование Where-Object командлета в конвейере для фильтрации.
  • Regex (^Get-|Linux) соответствует либо Get- в начале строки (^) или (|) подстроки Linux в любом месте в строка.
    Следовательно, это регулярное выражение соответствует строкам, которые вы не хотите, и, используя отрицательную форму -match - -notmatch - вы, следовательно, исключите те Строки, по желанию.


Если вы действительно хотите выразить свое регулярное выражение как положительное совпадение :

PS> $string -match '^(?!Get)((?!Linux).)*$'
Put-WindowsDevel

Обратите внимание, однако, что это регулярное выражение не только намного сложнее, но и будет работать хуже (хотя и незначительно).


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

Часть .*(?!Linux) вашего регулярного выражения, включающая отрицательное прогнозное утверждение ((?!...)) - не эффективна для исключения строк, содержащих подстроку Linux; e.g.:

PS> 'Linux' -match '.*(?!Linux)'
True # !!

Причина в том, что .* соответствует всей строке, а , тогда смотрит вперед, чтобы увидеть, если Linux нет - что, очевидно, верно в конце строки.

Чтобы эффективно исключить подстроку, утверждение должно применяться к каждому символу всей строки :

PS> '', 'inux', 'Linux', 'a Linux', 'aLinuxb' -match '^((?!Linux).)*$'
                  # '' (empty string) matched
inux              # 'inux' matched

Обратите внимание, как 'Linux', 'a Linux' и 'aLinuxb' были правильно исключены.

0 голосов
/ 12 марта 2019

это похоже на то, что вы ищете [ ухмылка ] ...

$StringList = @(
    'Get-WindowsDevel'
    'Put-WindowsDevel'
    'Get-LinuxDevel'
    'Put-LinuxDevel'
    )

$ExcludeList = @(
    '^get'
    'linux'
    )
$RegexExcludeList = $ExcludeList -join '|'

$StringList -notmatch $RegexExcludeList

вывод ...

Put-WindowsDevel
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...