Simon Elms
Simon Elms

Reputation: 19688

PowerShell split on "(" throws error: "Not enough )'s."

I've come across a weird "bug" or foible in PowerShell, trying to split a string on "(". Can anyone tell me what's going on, and if there is an easy work-around?

Here's the code:

$description = 'Get-ParsedData($Data)'
$description -split "("

Result:

parsing "(" - Not enough )'s.
At line:1 char:1
+ $description -split "("
+ ~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (:) [], ArgumentException
    + FullyQualifiedErrorId : System.ArgumentException

I've tried using '(' as well as "(", and also

$description -split [char]0x0028

All result in the same error message: parsing "(" - Not enough )'s.

In the end I got around the problem with the following code, which works:

$description.SubString(0, $description.IndexOf('('))

However, I'm still curious as to why I was getting the original error and whether there is a simple work-around.

Upvotes: 1

Views: 979

Answers (1)

Mathias R. Jessen
Mathias R. Jessen

Reputation: 174545

-split is a regular expression operator, and ( needs to be escaped (\():

$description -split "\("

The error message "Not enough )'s" might seem strange at first, but the reason ( needs to be escaped in regular expressions is that parentheses are used for grouping constructs:

PS C:\> 'abc' -split '(b)'
a
b
c

In the example above, we split on b, but "capture" it's value by enclosing it in ().

So when you pass the string "(" as a pattern, the regex engine sees it and goes "that ( is the start of a capture group", and since it can't find a corresponding ), it throws that error.

You can also use the [regex]::Escape() method to automatically escape any literal character in a regex pattern:

$splitPattern = [regex]::Escape("(")
$description -split $splitPattern

Alternatively, use the String.Split() method which only does simple substring replacement (and ( therefore doesn't need escaping):

$description.Split("(")

Upvotes: 8

Related Questions