Вы можете попробовать:
^\((\d{3})\)\s*(\d{3})-(\d{4})(?: ext(\d{5}))?$
Объяснение приведенного выше регулярного выражения:
^, $
- Представляет начало и конец строки соответственно.
\((\d{3})\)
- Представляет первую группу захвата, соответствующую цифрам внутри ()
.
\s*
- соответствует символу пробела ноль или более раз.
(\d{3})-
- представляет секунду группа захвата, захватывающая ровно 3 цифры, за которыми следует -
.
(\d{4})
- представляет третью группу захвата, совпадающую с цифрами ровно 4 раза.
(?: ext(\d{5}))?
-
(?:
Представляет группу без захвата -
ext
- после пробела и литерала ext
. (\d{5})
- представляет цифры ровно 5 раз. )
- Закрытие незахваченной группы. ?
- Представляет отправляет квантификатор, делая всю невыявленную группу необязательной.

You can find the sample demo of the above regex in здесь.
Команды Powershell:
PS C:\Path\To\MyDesktop> $input_path='C:\Path\To\MyDesktop\InputFile.txt'
PS C:\Path\To\MyDesktop> $output_path='C:\Path\To\MyDesktop\outFile.txt'
PS C:\Path\To\MyDesktop> $regex='^\((\d{3})\)\s*(\d{3})-(\d{4})(?: ext(\d{5}))?$'
PS C:\Path\To\MyDesktop> select-string -Path $input_path -Pattern $regex -AllMatches | % { "Phone Number: $($_.matches.groups[1])$($_.matches.groups[2])$($_.matches.groups[3]) Extension: $($_.matches.groups[4])" } > $output_path
Пример результата: Результат