Попытка сопоставить это с помощью регулярных выражений в PowerShell - PullRequest
1 голос
/ 05 ноября 2011

Я пытаюсь использовать регулярные выражения для сопоставления определенных строк в файле, но у меня возникли некоторые проблемы.

Файл содержит такой текст:

Mario, 123456789
Luigi, 234-567-890
Nancy, 345 5666 77533
Bowser, 348759823745908732589
Peach, 534785
Daisy, 123-456-7890

Я пытаюсь сопоставить только цифры как XXX-XXX-XXX или XXX XXX XXX.

Я пробовал несколько разных способов, но он всегда ожидает чего-то, чего я не хочу, или он говорит мне, что все ложно.

Я использую PowerShell для этого.

Сначала я попробовал:

{$match = $i -match "\d{3}\-\d{3}\-\d{3}|\d{3}\ \d{3}\ \d{3}"
Write-Host $match}

Но когда я это делаю, это соответствует длинному сильному чисел и XXX-XXX-XXXXX.

Я прочитал что-то, сказав, что n будет соответствовать точному количеству, поэтому я попробовал это ...

{$match = $i -match "\d{n3}\-\d{n3}\-\d{n3}|\d{n3}\ \d{n3}\ \{n3}"
Write-Host $match}

Это сделало все ложным ...

Итак, я попробовал

{$match = $i -match "\d\n{3}\-\d\n{3}\-\d\n{3}|\d\n{3}\ \d\n{3}\ \d\n{3}"

Я также попробовал ленивый квантификатор, ?:

{$match = $i -match "\d{3?}\-\d{3?}\-\d{3?}|\d{3?}\ \{3?}\ \{3?}"
Write-Host $match}

Все еще ложь ...

Последнее, что я попробовал, было это ...

{$match = $i -match "\d[0-9\{3\}\-\d[0-9]\{3\}\-\d[0-9]{3\}|\d[0-9]\{3\}\ \d[0-9]\{3}\ \d[0-9]\{3\}"<br>
Write-Host $match}

Все еще не повезло ...

Ответы [ 6 ]

1 голос
/ 05 ноября 2011

Следующий шаблон дает два совпадения:

Get-Content .\test.txt | Where-Object {$_ -match '\d{3}[-|\s]\d{3}[-|\s]\d{3}'}

Луиджи, 234-567-890
Daisy, 123-456-7890

Если вы хотите исключить последнее совпадение, добавьте якорь '$' (представляет конец строки:

Get-Content .\test.txt | Where-Object {$_ -match '\d{3}[-|\s]\d{3}[-|\s]\d{3}$'}

Луиджи, 234-567-890

Если вы хотите быть очень конкретным и сопоставлять строки от начала до конца (используйте якорь ^, обозначает начало строки):

Get-Content .\test.txt | Where-Object {$_ -match '^\w+,\s+\d{3}[-|\s]\d{3}[-|\s]\d{3}$'}

Луиджи, 234-567-890

0 голосов
/ 09 февраля 2012

Вы также можете использовать Select-String :

Select-String '(\d{3}[ -]){2}\d{3}$' .\file.txt | % {$_.Line}
0 голосов
/ 05 ноября 2011

При манипулировании данными в PowerShell обычно рекомендуется создавать объекты, представляющие данные (в конце концов, PowerShell - это все об объектах). Фильтрация на основе свойств объекта обычно проще и надежнее. Ваша проблема - хороший пример. Вот что мы ищем:

  • чел. : $ чел.
  • где : где
  • номер этого человека : $ _. Номер
  • совпадений : -match
  • шаблон
  • начиная с трех цифр : ^ \ d {3}
  • , за которыми следуют три цифры между тире или пробелами : (- \ d {3} - | \ \ d {3} \)
  • заканчивается тремя цифрами : \ d {3} $

Ниже приведен весь скрипт:

$persons = import-csv -Header "name", "number" -delimiter "," data.csv
$persons | where {$_.number -match "^\d{3}(\-\d{3}\-|\ \d{3}\ )\d{3}$"}
0 голосов
/ 05 ноября 2011

Как сказал Гедеон, ваше первое - лучшее место для старта.

"\b\d{3}\-\d{3}\-\d{3}\b|\b\d{3}\ \d{3}\ \d{3}\b"

Специальный символ \b, добавляемый до и после каждого оператора, является границей слова - в основном это пробел, символ новой строки или пунктуация, например точка или запятая. Это гарантирует, что 9999 не соответствует, но 999. соответствует.

0 голосов
/ 05 ноября 2011

Попробуйте это:

/(\d+[- ])+\d+/

Лучше не иметь таких жестких регулярных выражений, если только вы не уверены, что ваш ввод не изменится.

Таким образом, это регулярное выражение соответствует хотя бы цифре, затем жадно ищет дополнительные цифры, после которых ставится пробел или тире. Это также повторяется в максимально возможной степени, после чего следует по крайней мере еще одна цифра.

0 голосов
/ 05 ноября 2011

Ваш первый ответ самый близкий.{3} соответствует ровно 3 символам.Я думаю, что n, который вы видели, должен был представлять любое число, а не фактический n символ.Причина, по которой он соответствует длинным строкам, заключается в том, что вы указали только то, что для совпадения необходимо найти 3 цифры, тире или пробел, 3 цифры, тире или пробел, а затем еще 3 цифры.Вы не указали, что он не будет учитываться, если после этого появятся другие цифры.

Чтобы не совпадать, когда есть число после, вы можете использовать отрицательный прогноз .

(\d{3}-\d{3}-\d{3}|\d{3}\ \d{3}\ \d{3})(?!\d)

В качестве альтернативы, если вы хотите совпадать только в конце строки, возможно, с завершающим пробелом

(\d{3}-\d{3}-\d{3}|\d{3}\ \d{3}\ \d{3})\s*$
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...