Как я могу разобрать номер телефона в Perl? - PullRequest
1 голос
/ 14 января 2010

Я пытаюсь получить любые цифры перед известным номером строки телефона, если они существуют (в Perl).Тире не будет, только цифры.

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

$input          $digits       $number
'8675309'       ''            '8675309'
'8008675309'    '800'         '8675309'
'18888675309'   '1888'        '8675309'
'18675309'       '1'           '8675309'
'86753091'      not a match

/8675309$/ это будет соответствовать тому, как захватить предварительные цифры в одном регулярном выражении?

Ответы [ 6 ]

9 голосов
/ 14 января 2010

Некоторые регулярные выражения работают лучше назад, чем вперед. Поэтому иногда полезно использовать sexeger, а не регулярные выражения.

my $pn = '18008675309';

reverse($pn) =~ /^9035768(\d*)/;
my $got = reverse $1;

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

В этом случае выигрыш при возврате меньше, чем если бы у вас было регулярное выражение для извлечения номера телефона:

Regex:   /^(\d*)\d{7}$/
Sexeger: /^\d{7}(\d*)/

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

2 голосов
/ 14 января 2010
my($digits,$number);
if ($input =~ /^(\d*)(8675309)$/) {
  ($digits,$number) = ($1,$2);
}

Квантор * является жадным, но это означает, что он максимально соответствует , но при этом допускает совпадение . Итак, изначально, да, \d* пытается сожрать все цифры в $number, но неохотно отдает символ за символом, с которым сопоставляется, до тех пор, пока весь шаблон не будет успешно сопоставлен.

Другой подход - отрубить хвост:

(my $digits = $input) =~ s/8675309$//;

Вы можете сделать то же самое без использования регулярного выражения:

my $digits = $input;
substr($digits, -7) = "";

Выше, по крайней мере, с perl-5.10-1, можно даже сжать до

substr(my $digits = $input, -7) = "";
1 голос
/ 28 октября 2011

Существует пакет Perl, который работает как минимум с телефонными номерами в Великобритании и США.

Он называется Number :: Phone, а код находится где-то на сайте cpan.org.

1 голос
/ 14 января 2010

Специальные переменные регулярного выражения $ `и $ & являются еще одним способом получения этих фрагментов информации. Они содержат содержимое данных, предшествующих совпадению, и само сопоставление соответственно.

   if ( /8675309$/ )
      {
      printf( "%s,%s,%s\n", $_, $`, $& );
      }
   else
      {
      printf( "%s,Not a match\n", $_ );
      }
0 голосов
/ 14 января 2010

Я не могу понять проблему. Почему есть разница между первым и четвертым примерами:

'8675309'    ''   '8675309'  
...  
'8675309'    '1'  '8675309'

Если все, что вам нужно, это отделить последние семь цифр от всего остального, вы могли бы сказать это так, а не приводить в замешательство примеры. Регулярное выражение для этого будет:

/ (\ д *) (\ d {7,7}) $ /

Если вы не просто указали гипотетическое число и действительно ищете только строки с '8675309' (кажется странным), замените '\ d {7,7}' на '8675309'.

0 голосов
/ 14 января 2010

Как насчет /(\d)?(8675309)/? UPDATE:

упс, что должно было быть /(\d*)(8675309)/

...