PowerShell разделить на «(» выдает ошибку: «Недостаточно)».

#powershell

#powershell

Вопрос:

Я столкнулся со странной «ошибкой» или недостатком в PowerShell, пытаясь разделить строку на «(«. Кто-нибудь может сказать мне, что происходит, и есть ли простое решение?

Вот код:

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

Результат:

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

Я пробовал использовать '(' так же, как "(" , а также

 $description -split [char]0x0028
  

Все приводят к одному и тому же сообщению об ошибке: parsing "(" - Not enough )'s.

В конце концов я решил проблему с помощью следующего кода, который работает:

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

Тем не менее, мне все еще любопытно, почему я получал исходную ошибку и есть ли простой обходной путь.

Ответ №1:

-split является оператором регулярного выражения, и ( его необходимо экранировать ( ( ):

 $description -split "("
  

Сообщение об ошибке «Недостаточно )’s» на первый взгляд может показаться странным, но причина, по которой ( необходимо избегать в регулярных выражениях, заключается в том, что круглые скобки используются для группировки конструкций:

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

В приведенном выше примере мы разделили на b , но «захватили» это значение, заключив его в () .

Итак, когда вы передаете строку "(" в качестве шаблона, механизм регулярных выражений видит ее и сообщает «это ( начало группы захвата», и поскольку он не может найти соответствующую ) , он выдает эту ошибку.

Вы также можете использовать [regex]::Escape() метод для автоматического экранирования любого буквенного символа в шаблоне регулярных выражений:

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

В качестве альтернативы используйте String.Split() метод, который выполняет только простую замену подстроки (и ( поэтому не нуждается в экранировании):

 $description.Split("(")