Reputation: 368
I'm trying to write a where clause in Powershell using a regular expression that will only match lines (items in an array) that do not begin with [ AND do not end with ] (ini headers).
$test = @('test', '[test]', '[te]st', 'te[st]')
The below is as far as I could get. It matches only 'test'.
$test | where-object {$_ -match '^(?!\[).+(?<!\])$'}
'test', '[te]st' and 'te[st]' should be matched. Thank you.
Upvotes: 2
Views: 1306
Reputation: 68331
You can simplify that by utilizing the regex ^ and $ anchors and avoid the lookarounds. Lookaround operations are less efficient than direct matches, and should be avoided if a direct match solution will work.
$test = @('test', '[test]', '[te]st', 'te[st]')
$test -notmatch '^\s*\[.+\]\s*$'
test
[te]st
te[st]
The \s* on either end will account for any leading or trailing spaces in the lines.
Upvotes: 2
Reputation: 2306
Can't you look for patterns that do start with [ and end with ] and just check that the word doesnt match the regex? That would make the regex much easier:
\[[^\]]*\]
Upvotes: 0
Reputation: 20486
Problem
In [te]st
, the initial negative lookahead fails.
In te[st]
, the final negative lookbehind fails.
Solution
We need to use the alternator |
to make sure either one or the other scenario is valid..if both lookarounds fail, then we won't get a match:
^ (?# match the beginning of the string)
(?: (?# start non-capturing group)
(?!\[) (?# negative lookahead for [)
.+ (?# match 1+ characters)
| (?# OR)
.+ (?# match 1+ characters)
(?<!\]) (?# negative lookbehind for ])
) (?# end non-capturing group)
$ (?# match the end of the string)
Note: I put the alternation into a non-capturing group so that I do not need to include the anchors ^
and $
around each possible statement.
Upvotes: 4