atownson
atownson

Reputation: 368

Regular Expression to match lines not starting with [ and not ending with ] (ini headers)

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

Answers (3)

mjolinor
mjolinor

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

Farhad Alizadeh Noori
Farhad Alizadeh Noori

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

Sam
Sam

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)

Demo


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

Related Questions