Слишком жесткое регулярное выражение

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

([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})

Он отлично работает на таких числах, как:

555-555-5555 (555)555-5555 (555) 555-5555

Однако, если в строке есть дополнительное место, он не находит телефон.
555 -555-5555 (555)555- 5555 (555) 555 -5555

Может ли он быть изменен, чтобы предусмотреть пробел или два? Мой ввод происходит от OCR, а не от пользователя, поэтому я не могу требовать форматированного ввода.

Благодарю.

2

Решение

Согласно вашим примерам вы могли бы использовать

[(\d](?:(?!\h{2,})[-\d()\h])*\d

Увидеть демо на regex101.com.


То есть

[(\d]          # one of ( or 0-9
(?:            # a non-capturing group
(?!\h{2,}) # make sure not 2+ horizontal whitespaces are immediately ahead
[-\d()\h]  # then match one of -, 0-9, () or whitespaces
)*             # zero or more times
\d             # the end must be a digit

Это вариация закаленный жадный жетон.


В PHP это могло быть

<?php
$data = <<<DATA
555-555-5555   (555)555-5555    (555) 555-5555

However, if there\'s an extra space inside the string it does not find the phone. 555 -555-5555   (555)555- 5555    (555) 555 -5555
DATA;

$regex = '~[(\d](?:(?!\h{2,})[-\d()\h])*\d~';

preg_match_all($regex, $data, $matches);
print_r($matches);
?>

Который дает

Array
(
[0] => Array
(
[0] => 555-555-5555
[1] => (555)555-5555
[2] => (555) 555-5555
[3] => 555 -555-5555
[4] => (555)555- 5555
[5] => (555) 555 -5555
)

)
1

Другие решения

Если я понял, вы хотите использовать только регулярное выражение, так что вы можете добавить \s* в каждой группе шаблонов, как

([0-9]{3})\)?\s*[-. ]?\s*([0-9]{3})\s*[-. ]?\s*([0-9]{4})\s*

Это основано на вашем скрипте запроса

Здесь ДЕМО-ПРИМЕР

0

Я чувствую, что вы просите очень мягкую / инклюзивную модель.

Этот довольно простителен: /\(?\d{3}\)? {0,2}[-.]? {0,2}\d{3} {0,2}[-.]? {0,2}\d{4}/

Pattern Demo Link

Это будет соответствовать всем этим вариантам (… и больше):

555-555-5555
(555)555-5555
(555) 555-5555
555 -555-5555
(555)555- 5555
(555) 555 -5555
555.555-5555
555.555.5555
5555555555
555-555.5555
(555)5555555
(555).555.5555
(555)-555-5555
(555555-5555
555)-555-5555
555555-5555
555 5555555
555 555 5555
555 - 555 - 5555
555555  .  5555

Логика шаблона находится в следующем порядке:

  • разрешить необязательный (,
  • требуется 3 цифры
  • разрешить необязательный )
  • разрешить ноль, один или два буквенных пробела
  • разрешить дополнительный дефис или точку
  • разрешить ноль, один или два буквенных пробела
  • требуется 3 цифры
  • разрешить ноль, один или два буквенных пробела
  • разрешить дополнительный дефис или точку
  • разрешить ноль, один или два буквенных пробела
  • требуется 4 цифры
0

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

~[(\d](?:\b\d{3}\)(?=.{3,5}\W\b) {0,2}\d{3}|\B\d{2}(?=.{4,6}\W\b)(?:- ?| -? ?)\d{3})(?:- ?| -? ?)\d{4}\b~

демонстрация

Тот же шаблон в более читабельном:

~
[(\d]  # first character discrimination technic (avoid the cost of an alternation
# at the start of the pattern)
(?: # with brackets
\b \d{3} \)
(?= .{3,5} \W \b )
\g<spb> \d{3}
| # without brackets
\B \d{2} # you can also replace \B with (?<=\b\d) to check the word-boundary
(?= .{4,6} \W \b )
\g<sp> \d{3}
)
\g<sp> \d{4} \b

# subpattern definitions:
(?<spb> [ ]{0,2} ){0}             # separator after bracket
(?<sp> - [ ]? | [ ] -? [ ]? ){0}  # other separators
~x

демонстрация

Не стесняйтесь менять - в [.-] или определить ваши собственные разрешенные разделители. Не забудьте в этом случае изменить также квантификаторы в прогнозных данных. Кроме того, если вы хотите, чтобы второй разделитель был пустым, отметьте границу после последней цифры вместо границы перед первой цифрой последней группы.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector