Perl: форматирование номера телефона в США на основе ввода - PullRequest
0 голосов
/ 14 октября 2011

Этот не ответил на мой вопрос.

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

  • полное число : (XXX) XXX-XXXX
  • полный номер : XXX / XXX-XXXX
  • полный номер : XXXXXXXXXX
  • без кода города : XXX-XXXX
  • без кода города : XXXXXXX
  • только расширение : XXXX

Так что, если вы перепрограммируете его только для цифр s/[^\d]//g, вы получите 1 из 3 вариантов:

  • XXXXXXXXXX
  • XXXXXXX
  • XXXX

Который я хотел бы отформатировать так:

  • XXX / XXX-XXXX
  • XXX-XXXX
  • XXXX

Является ли лучший способ сделать это, чтобы сделать if операторов на основе длины? Или есть более однострочный подход?

Ответы [ 5 ]

5 голосов
/ 14 октября 2011

Я бы просто использовал if операторы, потому что они намного понятнее и проще для расширения:

if (length($number) == 4) {
  # extension
} elsif (length($number) == 7) {
  # no area code
} elsif (length($number) == 10) {
  # full number
} else {
  die "unsupported number";
}

Если вы используете Perl 5.10 или выше, вы можете использовать switch:

use feature "switch";

given (length($number) {
  when (4) { # extension }
  when (7) { # no area code }
  when (10) { # full number }
  default { die "unsupported number"; }
}

Любой из них дает преимущество в том, что его легко изменить, например, взять число, начинающееся с 1 (т. Е. 1-555-123-4567).

1 голос
/ 14 октября 2011

Это должно сделать это:

perl -pne's;(?:\(?(\d{3})[\)/]?\s*)?(?:(\d{3})-?)?(\d{4});$1/$2-$3;||die("bad #: $_") and s;^/-?;;'

Пример:

$ echo "(123)456-7890
(123) 456-7890
123/456-7890
1234567890
456-7890
7890
foobar
" |perl -pne's;(?:\(?(\d{3})[\)/]?\s*)?(?:(\d{3})-?)?(\d{4});$1/$2-$3;||die("bad #: $_") and s;^/-?;;'
123/456-7890
123/456-7890
123/456-7890
123/456-7890
456-7890
7890
bad number: foobar at -e line 1, <> line 7.
1 голос
/ 14 октября 2011

Вы можете использовать последовательность подстановок.

s#[^\d]##g;
s#(\d{3})(\d{4})$#$1-$2#;
s#(\d{3})(\d{3})-#$1/$2-#;

Вторая подстановка не удастся (т. Е. Не даст эффекта), если на входе меньше 7 цифр, и третья подстановка не получится, если на входеимеет менее 10 цифр.

0 голосов
/ 15 октября 2011
for(<DATA>){
  /^.*?: \s* \(? (\d{3})?? [)\/]? \s* (\d{3})? \s* [-]? \s* (\d{4}) \s* $/x;
  print "$&\t";
  print "$1 / " if $1;
  print "$2 - " if $2;
  print "$3\n"  if $3;      
}


__DATA__
* full number: (123) 456-7890
* full number: 123/456-7890
* full number: 1234567890
* no area code: 456-7890
* no area code: 4567890
* extension only: 7890

OUTPUT

* full number: (123) 456-7890
123 / 456 - 7890
* full number: 123/456-7890
123 / 456 - 7890
* full number: 1234567890
123 / 456 - 7890
* no area code: 456-7890
456 - 7890
* no area code: 4567890
456 - 7890
* extension only: 7890
7890

Вы также можете использовать именованные захваты, такие как (?<area>\d{3}), чтобы улучшить читаемость!

0 голосов
/ 15 октября 2011

CodePad

sub phoneFormat{
    my @sigils  = ('+','/','-');            # joiners
    $_ = reverse(shift);                    # input; reversed for matches
    @_ = grep{defined} unpack "A4A3A3A1",$_;    # match, starting with extension; and remove unmatched
    $_ = join('', map {$_ . pop @sigils } @_ ); # add in the delimiters
    ($_ = reverse) =~ s/^[^\d]+//;          # reverse back and remove leading non-digits
    $_;
}

print phoneFormat('012')         , "\n";    # (blank)
print phoneFormat('0123')        , "\n";    # 0123
print phoneFormat('0123456')     , "\n";    # 012-3456
print phoneFormat('0123456789')  , "\n";    # 012/345-6789
print phoneFormat('01234567899') , "\n";    # 0+123/456-7899
print phoneFormat('012345678999') , "\n";   # 1+234/567-8999
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...