Perl:根据输入格式化美国电话号码

时间:2011-10-14 15:49:51

标签: perl

This 没有回答我的问题。

可能的输入(可能有空格):

  • 完整号码 :( XXX)XXX-XXXX
  • 完整号码 :XXX / XXX-XXXX
  • 完整号码 :XXXXXXXXXX
  • 无区号 :XXX-XXXX
  • 无区号 :XXXXXXX
  • 仅限 :XXXX

因此,如果您仅为数字s/[^\d]//g正则表达式,那么您希望获得3个选项中的1个:

  • XXXXXXXXXX
  • XXXXXXX
  • XXXX

我想这样格式化:

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

执行此操作的最佳方法是根据长度执行if语句吗?或者是否有更多的单线方法?

5 个答案:

答案 0 :(得分:5)

我只是使用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 :(得分:1)

您可以使用一系列替换。

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

如果输入少于7位,则第二次替换将失败(即无效),如果输入少于10位,则第三次替换将失败。

答案 2 :(得分:1)

这应该这样做:

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.

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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

输出

* 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})之类的命名抓取来提高可读性!