2010-01-14 7 views
1

전화 번호가 존재하는 경우 펄의 알려진 번호 앞에 모든 숫자를 가져 오려고합니다. 대시는없고 숫자 만 있습니다.Perl에서 전화 번호를 파싱하려면 어떻게해야합니까?

예를 들어 줄 번호가 항상 8675309라는 것을 알고 있다고 가정 해 봅니다. 8675309에는 숫자를 캡처하고 싶을 수도 있고 없을 수도 있습니다. 실제로 선행 숫자의 수에는 제한이 없습니다.

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

/8675309$/이 하나의 정규식에 미리 자리를 캡처하는 방법과 일치합니다?

+2

왜 정규식을 사용합니까? index() 및 substr() 또는 split()은 어떻습니까? http://www.codinghorror.com/blog/archives/001016.html –

+0

사례가 있으십니까? perl에서 가변 길이 문자열 때문에 중첩 된 if 집합이 훨씬 더 복잡해 지겠지만 두렵습니다. – user210757

+0

http://stackoverflow.com/questions/2055988/how-cani-i-hobbs.htm에 대한 hobbs의 답변보기 국제 전화 번호 비교 (perl-international-phone-numbers-in-perl). –

답변

9

일부 정규 표현식에 있었다 haev해야 앞으로보다 더 뒤쪽으로 작동합니다. 그래서 때로는 정규 표현보다는 섹스가를 사용하는 것이 유용합니다.

my $pn = '18008675309'; 

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

정규식은 깨끗하고 입력 및 캡처 된 값을 반전 일부 fummery의 비용으로 추적 뒤로 많이 방지 할 수 있습니다.

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

이 기술이 유용 문제의 전체 클래스가 있습니다 :

되돌아 이득은 일반 전화 번호를 추출 정규식이 있다면 그것은 것보다이 경우 작다. 자세한 내용은 the sexeger post on Perlmonks을 참조하십시오.

+2

+1 "sexeger" – Ragepotato

+0

@Ragepotato, 나는 그 용어를 발명했으면 좋겠다. 그러나 그것은 기억에 남습니다. – daotoad

2
my($digits,$number); 
if ($input =~ /^(\d*)(8675309)$/) { 
    ($digits,$number) = ($1,$2); 
} 

* 정량 욕심이다,하지만 여전히 경기을 허용하면서 가능 만큼 일치하는 것을 의미한다. 그래서 처음에 \d*$number에있는 모든 자릿수를 먹어 치우려고하지만, 전체 패턴이 성공적으로 매치 될 때까지 매치 된 문자를 마지 못해 포기합니다. 당신은 정규 표현식을 사용하지 않고 동일한 작업을 수행 할 수

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

:

또 다른 방법은 꼬리를 잘라하는 것입니다

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

위, 적어도 펄-5.10-1와, 응축 될 수도 있음

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

내 혼란은 내가 (\ d *) 전체 문자열을 탐욕스럽게 생각했을 것이라고 생각하지만, 그렇게 보이지 않는다. 나는 당신이 옵션으로 욕심이 아닌 정규식을 만들어야한다고 생각 했단 말인가? – user210757

+0

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 가능한 한 많이 잡아서 시작한 다음 필요에 따라 후속 요구 사항을 충족 시키려고합니다. 'perl -Mre = debug -e '의 출력을 살펴보십시오. $ foo = "18008675309"; $ foo = ~/(\ d *) 8675309 /; '' – daotoad

0

/(\d)?(8675309)/? UPDATE :

으악 /(\d*)(8675309)/

+1

'^'및'$'앵커가 없으면 해당 패턴은 대상 문자열의 어느 곳에 나 일치 할 수 있습니다. –

1

정규식 특수 변수 $`및 $ &은 이러한 정보를 얻는 또 다른 방법입니다. 그들은 매치와 매치 자체에 선행하는 데이터의 내용을 가지고 있습니다.

if (/8675309$/) 
     { 
     printf("%s,%s,%s\n", $_, $`, $&); 
     } 
    else 
     { 
     printf("%s,Not a match\n", $_); 
     } 
0

나는이 문제를 이해하지 못할 수도 있습니다. 이유는 첫 번째와 네 번째 예는 차이가있다 : 당신이 원하는 모든 다른 모든 것들에서 마지막 7 개 자리를 분리하는 경우

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

, 당신은 그런 식으로 혼란 예제를 제공하기보다는 말했다 수 .있는 정말 그냥 가상 번호를 제공하지 않은 경우

/(\ D *) (\ d를 {7,7}) $/

및 : 그위한 정규식 것 '8675309'(이상하게 보임) 행을 찾는 경우 '\ d {7,7}'을 '8675309'로 바꿉니다.

+0

업데이트 됨 - 네 번째 예가 입력되어야 함 = '18675309' – user210757

1

적어도 영국 전화 번호와 미국 전화 번호를 처리하는 Perl 패키지가 있습니다.

전화 번호는 Number : Phone이고 코드는 cpan.org 사이트에 있습니다.

관련 문제