[regex] 정규식을 사용하여 전화 번호를 확인하는 방법

전화 번호를 확인하기 위해 포괄적 인 정규식을 작성하려고합니다. 이상적으로는 국제 형식을 처리하지만 다음을 포함하여 미국 형식을 처리해야합니다.

  • 1-234-567-8901
  • 1-234-567-8901 x1234
  • 1-234-567-8901 ext1234
  • 1 (234) 567-8901
  • 1.234.567.8901
  • 1/234/567/8901
  • 12345678901

나는 현재의 시도로 대답 할 것이지만, 누군가가 더 좋고 우아한 것을 기대하고 있습니다.



답변

더 나은 옵션 … 입력 할 때 숫자가 아닌 문자를 모두 제거하고 ( ‘x’및 선행 ‘+’부호 제외) +44 (0) ...국제 접두어를 사용하라는 요청 에 따라 영국이 비표준 형식으로 숫자를 쓰는 경향 이 있으므로주의하십시오. (특정한 경우에는 (0)완전히 폐기해야합니다 ).

그런 다음 다음과 같은 값으로 끝납니다.

 12345678901
 12345678901x1234
 345678901x1234
 12344678901
 12345678901
 12345678901
 12345678901
 +4112345678
 +441234567890

그런 다음 표시 할 때 하트 컨텐츠로 다시 포맷하십시오. 예 :

  1 (234) 567-8901
  1 (234) 567-8901 x1234


답변

적어도 북미에 대해서는 NANP 라는 사양이 있습니다.

원하는 것을 정확하게 지정해야합니다. 법적 구분 기호는 무엇입니까? 공백, 대시 및 마침표? 구분자가 허용되지 않습니까? 하나의 혼합 구분 기호를 사용할 수 있습니까 (예 : + 0.111-222.3333)? 확장 (예 : 111-222-3333 x 44444)은 어떻게 처리됩니까? 911과 같은 특수 숫자는 어떻습니까? 지역 번호는 선택 사항입니까, 아니면 필수입니까?

7 자리 또는 10 자리 숫자에 대한 정규식은 다음과 같습니다. 확장자는 허용되고 구분자는 공백, 대시 또는 마침표입니다.

^(?:(?:\+?1\s*(?:[.-]\s*)?)?(?:\(\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\s*\)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\s*(?:[.-]\s*)?)?([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})(?:\s*(?:#|x\.?|ext\.?|extension)\s*(\d+))?$


답변

.*

사용자가 전화 번호를 알려주려면 전화 번호를 올바르게 입력해야합니다. 그들이 당신에게 그것을주고 싶지 않다면 유효한 숫자를 입력하도록 강요하면 경쟁 업체의 사이트로 보내거나 정규식에 맞는 임의의 문자열을 입력하게됩니다. 나는 심지어 프리미엄 운세 운세 핫라인의 수를 찾아보고 그 대신에 들어가기를 유혹 할 수도 있습니다.

또한 다음 중 하나를 웹 사이트의 유효한 항목으로 간주합니다.

"123 456 7890 until 6pm, then 098 765 4321"  
"123 456 7890 or try my mobile on 098 765 4321"  
"ex-directory - mind your own business"


답변

또한 ” libphonenumber “Google 라이브러리를 참조하십시오. 나는 그것이 정규 표현식이 아니라는 것을 알고 있지만 정확히 원하는 것을합니다.

예를 들어 다음을 인식합니다.

15555555555

가능한 숫자이지만 유효한 숫자는 아닙니다. 또한 미국 이외의 국가를 지원합니다.

기능의 하이라이트 :

  • 전 세계 모든 국가 / 지역의 전화 번호 구문 분석 / 포맷 / 확인
  • getNumberType-숫자 자체를 기반으로 숫자의 유형을 가져옵니다. 유선, 모바일, 무료, 프리미엄 요금, 공유 비용, VoIP 및 개인 번호 (가능한 경우)를 구별 할 수 있습니다.
  • isNumberMatch -두 숫자가 동일 할 수 있는지에 대한 신뢰 수준을 얻습니다.
  • getExampleNumber/ getExampleNumberByType-필요한 전화 번호 유형을 지정하는 옵션과 함께 모든 국가 / 지역에 유효한 예시 번호를 제공합니다.
  • isPossibleNumber -전체 유효성 검사보다 훨씬 빠른 길이 정보 만 사용하여 전화 번호가 가능한지 빠르게 추측합니다.
  • isValidNumber -길이 및 접두사 정보를 사용하여 지역 전화 번호의 전체 유효성 검사
  • AsYouTypeFormatter -사용자가 각 숫자를 입력 할 때 즉시 전화 번호를 형식화합니다.
  • findNumbers -텍스트 입력에서 숫자를 찾습니다.
  • PhoneNumberOfflineGeocoder -전화 번호와 관련된 지리 정보를 제공합니다.

전화 번호 확인의 가장 큰 문제는 문화적으로 매우 다르다는 것입니다.

  • 미국
    • (408) 974–2042A는 유효한 미국 번호
    • (999) 974–2042유효한 미국 번호 가 아닙니다
  • 호주
    • 0404 999 999A는 유효한 호주의 수는
    • (02) 9999 9999유효한 호주 번호 이기도합니다
    • (09) 9999 9999유효한 호주 번호 가 아닙니다

정규식은 전화 번호의 형식을 확인하는 데는 좋지만 실제로 전화 번호 의 유효성 을 확인할 수는 없습니다.

전화 번호를 테스트하기 위해 간단한 정규 표현식을 건너 뛰고 Google과 같은 라이브러리를 사용하는 것이 좋습니다 libphonenumber(GitHub 프로젝트 링크) .

libphonenumber를 소개합니다!

더 복잡한 예제 중 하나를 사용 하면 다음 데이터1-234-567-8901 x1234 를 얻을 수 있습니다 (온라인 데모 링크) .libphonenumber

Validation Results

Result from isPossibleNumber()  true
Result from isValidNumber()     true

Formatting Results:

E164 format                    +12345678901
Original format                (234) 567-8901 ext. 123
National format                (234) 567-8901 ext. 123
International format           +1 234-567-8901 ext. 123
Out-of-country format from US  1 (234) 567-8901 ext. 123
Out-of-country format from CH  00 1 234-567-8901 ext. 123

따라서 전화 번호가 유효한지 여부를 알 수있을뿐만 아니라 로캘에서 일관된 전화 번호 형식을 얻습니다.

보너스로, libphonenumber전화 번호의 유효성을 확인할 수있는 많은 데이터 세트가 있으므로 +61299999999(국제 버전 (02) 9999 9999) 과 같은 숫자를 확인하면 형식이 지정된 유효한 숫자로 리턴됩니다.

Validation Results

Result from isPossibleNumber()  true
Result from isValidNumber()     true

Formatting Results

E164 format                    +61299999999
Original format                61 2 9999 9999
National format                (02) 9999 9999
International format           +61 2 9999 9999
Out-of-country format from US  011 61 2 9999 9999
Out-of-country format from CH  00 61 2 9999 9999

libphonenumber는 또한 전화 번호가 감지 된 위치를 파악하고 전화 번호에서 시간대 정보를 얻는 것과 같은 많은 추가 이점을 제공합니다.

PhoneNumberOfflineGeocoder Results
Location        Australia

PhoneNumberToTimeZonesMapper Results
Time zone(s)    [Australia/Sydney]

그러나 잘못된 호주 전화 번호 ( (09) 9999 9999)는 유효한 전화 번호가 아님을 반환합니다.

Validation Results

Result from isPossibleNumber()  true
Result from isValidNumber()     false

Google 버전에는 Java 및 Javascript 용 코드가 있지만 사람들은 Google i18n 전화 번호 데이터 세트를 사용하는 다른 언어 용 라이브러리도 구현했습니다.

항상 한 로케일의 숫자를 받아들이고 항상 하나의 형식으로되어 있다고 확신하지 않는 한, 자신의 코드를 작성하지 말고 전화 번호를 확인하고 표시하기 위해 libphonenumber를 사용하는 것이 좋습니다.


답변

/^(?:(?:\(?(?:00|\+)([1-4]\d\d|[1-9]\d?)\)?)?[\-\.\ \\\/]?)?((?:\(?\d{1,}\)?[\-\.\ \\\/]?){0,})(?:[\-\.\ \\\/]?(?:#|ext\.?|extension|x)[\-\.\ \\\/]?(\d+))?$/i

이것은 다음과 일치합니다.

 - (+351) 282 43 50 50
 - 90191919908
 - 555-8909
 - 001 6867684
 - 001 6867684x1
 - 1 (234) 567-8901
 - 1-234-567-8901 x1234
 - 1-234-567-8901 ext1234
 - 1-234 567.89/01 ext.1234
 - 1(234)5678901x1234
 - (123)8575973
 - (0055)(123)8575973

$ n이면 다음을 저장합니다.

  1. 국가 표시기
  2. 전화 번호
  3. 신장

https://www.regexpal.com/?fam=99127에서 테스트 할 수 있습니다.


답변

모든 공백을 제거하는 대답은 깔끔하지만 실제로 발생하는 문제를 해결하지는 못합니다. 즉 정규 표현식을 찾는 것입니다. 예를 들어 웹 페이지를 다운로드하고 정규식을 사용하여 모든 전화 번호를 추출하는 테스트 스크립트를 사용하십시오. 어쨌든 정규식이 필요하기 때문에 정규식이 모든 작업을 수행하도록 할 수도 있습니다. 나는 이것을 생각해 냈다.

1?\W*([2-9][0-8][0-9])\W*([2-9][0-9]{2})\W*([0-9]{4})(\se?x?t?(\d*))?

다음은이를 테스트하는 펄 스크립트입니다. 일치하면 $ 1에 지역 번호가 포함되고 $ 2와 $ 3에 전화 번호가 포함되며 $ 5에 내선 번호가 포함됩니다. 내 테스트 스크립트는 인터넷에서 파일을 다운로드하고 그 안에있는 모든 전화 번호를 인쇄합니다.

#!/usr/bin/perl

my $us_phone_regex =
        '1?\W*([2-9][0-8][0-9])\W*([2-9][0-9]{2})\W*([0-9]{4})(\se?x?t?(\d*))?';


my @tests =
(
"1-234-567-8901",
"1-234-567-8901 x1234",
"1-234-567-8901 ext1234",
"1 (234) 567-8901",
"1.234.567.8901",
"1/234/567/8901",
"12345678901",
"not a phone number"
);

foreach my $num (@tests)
{
        if( $num =~ m/$us_phone_regex/ )
        {
                print "match [$1-$2-$3]\n" if not defined $4;
                print "match [$1-$2-$3 $5]\n" if defined $4;
        }
        else
        {
                print "no match [$num]\n";
        }
}

#
# Extract all phone numbers from an arbitrary file.
#
my $external_filename =
        'http://web.textfiles.com/ezines/PHREAKSANDGEEKS/PnG-spring05.txt';
my @external_file = `curl $external_filename`;
foreach my $line (@external_file)
{
        if( $line =~ m/$us_phone_regex/ )
        {
                print "match $1 $2 $3\n";
        }
}

편집하다:

정규식에서 \ W *를 \ s * \ W? \ s *로 변경하여 조금 강화할 수 있습니다. 예를 들어 양식을 작성할 때 사용자 입력의 유효성을 검사하는 것과 관련하여 정규식을 생각하지 않았지만 이러한 변경으로 인해 정규식을 해당 목적으로 사용할 수 있습니다.

'1?\s*\W?\s*([2-9][0-8][0-9])\s*\W?\s*([2-9][0-9]{2})\s*\W?\s*([0-9]{4})(\se?x?t?(\d*))?';


답변

아무도이 스레드에 대한 답변으로 내 답변을 포함 시키기로 결정하기 전에 다른 SO 질문에 대해이 질문에 대답했습니다. 왜냐하면 아무도 항목을 요구하거나 요구하지 않는 방법을 다루지 않고 정규 표현식을 전달하는 사람이 없었기 때문입니다.

해당 사이트의 게시물을 통해 누구나 원하는 전화 번호 형식으로 자신의 정규식을 만드는 데 도움이되는 빠른 가이드를 만들었습니다. 다른 사이트에서와 같이 너무 제한적이라면 원하는 결과를 얻지 못할 수도 있으며 전 세계에서 가능한 모든 전화 번호를 받아들이는 “하나의 크기에 모두 맞는”솔루션이 없으며 선택한 형식으로 수락하기로 결정한 것만 있습니다. 자신의 책임하에 사용하십시오.

빠른 치트 시트

  • 표현식을 시작하십시오. /^
  • 공백이 필요한 경우 다음을 사용하십시오. [\s]또는\s
  • 당신이 괄호를 필요로 할 경우, 사용 [(]하고 [)]. \(and를 사용하면 \)추악하고 혼란 스러울 수 있습니다.
  • 선택 사항 인 것을 원한다면 그 ?뒤에
  • 하이픈을 원하면 -또는을 입력하십시오 [-]. 그러나 일련의 다른 문자를 맨 처음이나 마지막에 넣지 않으면 이스케이프해야 할 수도 있습니다. \-
  • 슬롯에서 다른 선택 사항을 승인하려면 옵션 주위에 대괄호를 넣으십시오 [-.\s]. 하이픈, 마침표 또는 공백이 필요합니다. 마지막 대괄호 뒤의 물음표는 해당 슬롯에 대한 모든 옵션을 선택합니다.
  • \d{3}: 000-999의 3 자리 숫자가 필요합니다. 의 속기입니다
    [0-9][0-9][0-9].
  • [2-9] : 해당 슬롯에 숫자 2-9가 필요합니다.
  • (\+|1\s)?: “plus”또는 1과 공백 (파이프 문자, |“는”또는 “)을 허용하고 선택 사항으로 만드십시오. “더하기”부호는 이스케이프되어야합니다.
  • 특정 숫자가 슬롯과 일치하도록하려면 숫자를 입력하십시오. [246]2, 4 또는 6 [77|78]이 필요합니다. 77 또는 78이 필요합니다.
  • $/ : 표현 끝내기