正規表現を使用して電話番号を検証する方法


920

電話番号を検証するための包括的な正規表現をまとめようとしています。理想的には国際フォーマットを処理しますが、以下を含む米国フォーマットを処理する必要があります。

  • 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

私の現在の試みでお答えしますが、誰かがより良いものやエレガントなものを持っていることを願っています。


3
ところで、使用している言語を指定する必要があります。すべての正規表現エンジンが同じ構文を持つわけではありません。
AndrewJFord 2008

9
このケースは答えでカバーされていますが、1ではなく+1のオプションを省略したようです。
エリック、

153
それ以外のすべての米国の電話番号に必要な555ものではありません911か?
Andrew Grimm、

41
逆に、555プレフィックスは偽の電話番号用に予約されています。これらの番号は実際の電話番号に接続されないことが保証されているため、テレビや映画でよく使用され、視聴者が番号に電話をかけたり、無邪気な嫌がらせをしたりすることがなくなります。
急いで

49
@rushinge それは数十年前には真実でしたが、もはや真実ではありません。555プレフィックスは特別ですが、555-0100から555-0199への接続なしで終了できることが保証されているのは、ごく一部の番号だけです。とにかく、アンドリューは冗談を言っていたと思います。
アダムデイビス

回答:


515

より良いオプション...入力時に数字以外のすべての文字( 'x'と先頭の '+'記号を除く)を削除するだけで+44 (0) ...、国際的なプレフィックスを使用するように要求されたときに英国が非標準形式で数字を書く傾向があるため、注意が必要です。(その特定のケースでは、(0)完全に破棄する必要があります)。

その後、次のような値になります。

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

次に、表示するときに、心のコンテンツに再フォーマットします。例えば

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

35
米国外からの数字の入力が許可されている場合、フォーマットコードは時間の無駄になります。
Daniel Earwicker、2009

26
これはすべて適切ですが、入力されたものが実際に電話番号であったかどうかは検証されません。たとえば、ユーザーが必要な10桁を入力しない場合はどうなりますか?これは、優れた正規表現検証と組み合わせる必要があります。
ヒュージェフナー、2010

108
質問を検討することは検証についてでした-これは本当に悪い答えです。
PlexQ 2012年

15
@PlexQ同意しない。元の問題は、可能なすべてのフォーマットオプションを処理しようとしたため、電話番号の検証を処理しようとしています。すべてを解決しようとするのではなく、入力を取り、「数値」だけが得られるまで、すべてのフォーマットの綿毛を「プレストリップ」してください。これにより2つの問題が解決します。結果のテストが簡単になり、表示用にレンダリングされた値をすべて一貫してフォーマットできることを確認できます。「コンプリケーターの手袋」に関するこの回答の最初のコメントは読みやすいです...時々、問題への回答は、別の方法でそれに取り組むことです。
scunliffe 2012年

29
これはどうしてこんなに投票数の多い答えなんだ?これは何も検証しません。さらに悪いことに、他のすべての電話番号検証質問はこれを参照しています...
jlars62

303

これには、少なくとも北米ではNANPと呼ばれる仕様があることがわかります。

必要なものを正確に指定する必要があります。法的区切り文字とは何ですか?スペース、ダッシュ、ピリオド?区切り文字は許可されていませんか?1つの区切り文字を混在させることはできますか(例:+ 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+))?$

7
ここでは拡張セクションなしです(ユーザーに別のフィールドにextを入力させます):^(?:(?:\ +?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})$
aarona

18
ここだけで10桁の電話番号と一致するバージョンがある(ない7桁843から1212など): /(?:(?:\+?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})/
ブライアン・アームストロング

8
10桁は()の市外局番を受け入れ、国コードとして1を前に付けることはできません(?:(?:(\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})
Brooke。

5
@StevenSoroka正規表現が私の仕事の主要な部分であるため、過去2年間、ジェフリーフリードルの本を私の机の上に置いてきました。正規表現を本当に理解するにはしばらく時間がかかります。時々、このサイトの読者は、特に電話番号表現のように多くのコーナーケースがあるドメインでは、自分で書くのではなく、単に既存の解決策を探しています。
ジャスティンR.

7
@ fatcat1111理解しましたが、ここでの応答の大部分は「私も」タイプの1回限りの正規表現であり、コーナーケースのいずれにも当てはまらない可能性があります。これらは、使用しようとしているすべてのWebサイトに到達し、誰かが中途半端な正規表現を使用したために郵便番号、電話番号、または電子メールアドレスを入力できません(例:+は電子メールアドレスの有効な文字です) )。このページの最良の応答は、ナプキンスクロール正規表現ではなく、ライブラリをユーザーに示します。
Steven Soroka

298
.*

ユーザーが自分の電話番号を教えたい場合は、電話番号が正しいことを信頼してください。彼らがあなたにそれを与えたくない場合は、有効な番号を入力するように強制すると、競合他社のサイトに送信されるか、正規表現に適合するランダムな文字列が入力されます。プレミアムレートホロスコープホットラインの番号を調べて、代わりに入力したくなるかもしれません。

また、次のいずれかをWebサイトの有効なエントリと見なします。

"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"

202
私はここの意見に同意しますが、電話番号が実際にユーザーの利益のために重要な何かに使用されようとしているときに検証を実行するとよい場合があります。ここでの最良の例は、購入のクレジットカード承認です。電話番号が間違っていると、認証が失敗する可能性があります。
先のとがった

53
ユーザーが自分の電話番号を入力したくない場合は、このフィールドをオプションにすることができますが、ユーザーが電話番号を入力する場合、有効な電話番号を入力するように要求するのは大したことでしょうか。
Joel McBeth

11
また、検証の役割は、他の方法では追加することを覚えていないかもしれないが、事実の後に推測できない可能性があるエリアコードなどを追加することを人々に思い出させることです。
ベンマッキンタイア

29
@Pointyしかし、正規表現の検証は役に立ちません。電話番号が正しいかどうかを実際に検証する唯一の方法は、実際にメッセージを送信すること(モバイルの場合)で、ユーザーが何らかの確認コードを使用して確認することです。これは、数値の正確さが重要な場合に行うことです。それ以外はすべて、ユーザーの便宜のために(すべてではありませんが)一部のタイプミスから保護し、何も検証しません。
Alex B

14
涼しい。私の電話番号は1 'OR 1 = 1-PWNEDです。xkcd.com/327 およびowasp.org/index.php/Testing_for_SQL_Injection_(OWASP-DV-005)を
アーロンニュートン

171

libphonenumber」のGoogleライブラリもご覧になることをお勧めします。私はそれが正規表現ではないことを知っていますが、それはあなたが望むものを正確に行います。

たとえば、次のことを認識します。

15555555555

は可能な数値ですが、有効な数値ではありません。また、米国以外の国もサポートしています。

機能のハイライト:

  • 世界のすべての国/地域の電話番号を解析/フォーマット/検証します。
  • getNumberType-番号自体に基づいて番号のタイプを取得します。固定回線、モバイル、フリーダイヤル、プレミアムレート、共有コスト、VoIP、および個人番号(可能な場合)を区別できます。
  • isNumberMatch -2つの数値が同じであるかどうかの信頼レベルを取得します。
  • getExampleNumber/ getExampleNumberByType-すべての国/地域に有効なサンプル番号を提供し、必要なサンプル電話番号のタイプを指定するオプションがあります。
  • isPossibleNumber -完全な検証よりもはるかに速く、長さ情報のみを使用することにより、番号が可能な電話番号であるかどうかをすばやく推測します。
  • isValidNumber -長さとプレフィックス情報を使用した地域の電話番号の完全な検証。
  • AsYouTypeFormatter -ユーザーが各桁を入力すると、オンザフライで電話番号をフォーマットします。
  • findNumbers -テキスト入力で数値を検索します。
  • PhoneNumberOfflineGeocoder -電話番号に関連する地理情報を提供します。

電話番号検証の最大の問題は、文化的に非常に依存していることです。

  • アメリカ
    • (408) 974–2042ある有効な米国の番号
    • (999) 974–2042有効な米国の番号ではありません
  • オーストラリア
    • 0404 999 999ある有効なオーストラリアの数
    • (02) 9999 9999また、有効なオーストラリアの番号です
    • (09) 9999 9999有効なオーストラリアの番号ではありません

電話番号の形式を確認するには正規表現で問題ありませんが、実際には電話番号の有効性を確認することはできません。

電話番号をテストするために単純な正規表現をスキップし、Google libphonenumber(GitHubプロジェクトへのリンク)などのライブラリを使用することをお勧めします。

libphonenumberのご紹介!

より複雑な例の1つを使用して、(オンラインデモへのリンク)から次のデータ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電話番号データセットを使用する他の言語のライブラリも実装されています。

常に1つのロケールからの番号を受け入れ、それらが常に1つの形式になることを確信している場合を除いて、このための独自のコードを記述せず、電話番号の検証と表示にlibphonenumberを使用することを強くお勧めします。



可能性のある番号かどうかを確認するときに、国コードを指定する必要はありませんか?PHPバージョンを使用していて、(0を実数に置き換える)のような英国の数値を入力する07700000000と、Missing or invalid default region.エラーが発生します。しかし、国コードを指定した場合は合格します。
BugHunterUK 2016年

参考:このライブラリは一部の国をサポートしていません、phpinterviewquestions.co.in
blog / ionic /

1
@BugHunterUK(およびこの質問に遭遇し、同じことを考えている人)は、数値を解析するときに、予想される地域を指定でき、ライブラリはその地域の非国際番号を探します。指定しない場合、有効な国際形式でないものはすべて拒否されます。
IMSoP 2018年

github.com/nyaruka/phonenumbersは、libphonenumberではなく、Googleが推奨する「公式」のGoパッケージになっているため、検討してください。
DeeZone、

78

/^(?:(?:\(?(?: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でテストできます


これは私が見た中で最も包括的な正規表現でした。それはあなたが削除するまで、周りを取得するのは簡単です^し、$または他の私が使用してそれを回避することができるよ[111] [111] [1111]111--111--1111など。(申し訳ありませんが、最後のコメントを削除しました)
bafromca 2014年

言い換えてください。これを理解できません:「^と$を削除するまで簡単に回避できます。そうしないと、[111] [111] [1111]を使用して回避できます」^とを取ったときに、それが「[111] [111] [1111]」を検証するという意味$ですか
Ismael Miguel

私はあなたの正規表現を使用して周りだ[111] [111] [1111]111--111--1111、私は削除されるまで、^および$正規表現から。
bafromca 2014年

11
^^^これは、コメントスレッドがチャットに参加してはならない理由の良い例です。私はこの会話がどのように行われるかに非常に興味があり、このReGexが私のアプリで使用できるほど頑丈かどうかを知る必要があります。残念ながら、チャットの会話はなくなりました。
Matt Cashatt 14

1
正直なところ、私はチャットに行きませんでした。説明を何度も求めたところ、情報がありませんでした。オンラインで見つけたあらゆる種類の数字を、複数の形式でいつでも自分で試すことができます。私がこれで試したことの1つは、複数の電話番号を使用することですが、周りにスペースがある場合はうまく機能しません。そして、私は桁数を数え、特定の量を強制するソリューションを見つけなければなりません。
Ismael Miguel 14

63

すべての空白を取り除くための答えはきちんとしていますが、それは提起されている問題、つまり正規表現を見つけることを実際には解決しません。たとえば、Webページをダウンロードし、正規表現を使用してすべての電話番号を抽出する私のテストスクリプトを見てみましょう。とにかく正規表現が必要なので、正規表現にすべての作業を行わせることもできます。私はこれを思いつきました:

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

これをテストするためのperlスクリプトを次に示します。一致すると、$ 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*))?';

2
FYI正規表現も一致します。(4570457-6789これはかなり一般的なタイプミスです。マッチグループも歪んでいます:rubular.com/r/TaTP0mHL5c
SooDesuNe

@SooDesuNe Prepending (^|[^\d\n])(複数行フラグがオンの場合)は、数値の直後に先行しないようにすることで、一般的な問題を回避します。
btown 2017年

これは北米中心であることに注意してください。「44 7911 123456」が欠落しています
ベンウィーラー

43

:私は誰のアイテム、regexsアウトだけ渡す必要はない/必要とする方法をアドレッシングなかったため、このスレッドで答えとして私の答えを含めることを決定する前に、別のSOの質問にこの質問に答え 、予期せぬ事を一致、正規表現、間違った作業を

そのサイトの私の投稿から、自分の希望する電話番号形式に対して独自の正規表現を作成するのを手助けするクイックガイドを作成しました。これは(他のサイトで行ったように)警告します。希望する結果が得られない可能性があり、世界中のすべての可能な電話番号を受け入れる「1つのサイズですべてに対応する」ソリューションはなく、選択した形式として受け入れることに決めたものだけです。自己責任。

クイックチートシート

  • 式を開始します。 /^
  • スペースが必要な場合は、次を使用します。 [\s]または\s
  • 括弧が必要な場合は、[(]およびを使用 し[)]ます。とを使用する\(\)醜く、混乱を招く可能性があります。
  • オプションにしたい場合は、?その後に置きます
  • あなたはハイフンをしたい場合は、単に入力します-[-]。ただし、他の一連の文字の最初または最後に配置しない場合は、エスケープする必要がある場合があります。 \-
  • スロットで異なる選択を受け入れる場合は、オプションを角括弧で囲みます。[-.\s]ハイフン、ピリオド、またはスペースが必要です。最後のブラケットの後の疑問符は、それらすべてをそのスロットに対してオプションにします。
  • \d{3}:3桁の番号が必要です:000-999。の略記 [0-9][0-9][0-9]
  • [2-9] :そのスロットには2〜9の数字が必要です。
  • (\+|1\s)?:「プラス」または1とスペース(パイプ文字、、|は「または」)を受け入れ、オプションにします。「プラス」記号はエスケープする必要があります。
  • 特定の番号をスロットに一致させる場合は、番号を入力します[246]。2、4、または6 [77|78]が必要です。77または78が必要です。
  • $/ :式を終了します

1
これは非常に便利ですが、{min、max}式を疑って探しています。手伝ってくれますか?
Ataboy Josef 2015

それが私たちが話している1桁の数字である場合(そしてそれに応じて一致させることができます)、[2-9]私がそこに置いたブロックを参照してください。つまり、最小値は2、最大値は9です。それに応じて調整してください。
vapcguy 2015年

30

私は最も簡単に書いた(ドットは必要なかったが)。

^([0-9 \(\)\ / \ + \-] *)$

後述するように、構造/順序ではなく、文字のみをチェックします


38
これは、技術的に無効な数の数を検証します。「-+()()())())))」のように。正規表現の読み方を学び、自分が何をしているかを理解できるようにします。
Steven Soroka 2013年

3
@StevenSoroka技術的には多くの無効なケースが許可される可能性がありますが、ユーザーが最も単純な可能な解決策で一般的な間違いを回避するのを助けることを考えた場合、これは行く方法です:)
happyhardik '23

2
これも空白と一致し、空の行
Wasim A.

1
@HappyHardik。確かに。基本的な検証のためのシンプルで強力な、ユーザーが複数のドット、ダッシュ、ブラケット、またはプラスを入力できるようにします。
dijipiji 2014

使用しただけで、多くの点で間違っています。たとえば、英国の電話番号は+44で始まる場合や、電話番号に(0)が含まれる場合があります。しかし、これはあなたの正規表現によれば有効ではありません。@Ismael Miguelの回答をお勧めします。それはうまく機能しますので、あなたの答えを修正することをお勧めします。
Stelios Voskos

22

あなたがフィールドにランダムなゴミがないことを確認したいだけなら(つまり、フォームスパマーから)、この正規表現はうまくいくはずです:

^[0-9+\(\)#\.\s\/ext-]+$

桁数、またはそれらの桁で有効な数値について特別な規則はないことに注意してください。数字、括弧、ダッシュ、プラス、スペース、ポンド、アスタリスク、ピリオド、コンマ、または文字のみが検証されます。ext存在しています。

国際番号およびローカリゼーション形式と互換性がある必要があります。一部の地域で角括弧、中括弧、または山括弧を許可する必要があると思いますか?(現在、それらは含まれていません)。

桁ごとのルール(たとえば、米国の市外局番やプレフィックス(交換コード)を200〜999の範囲にする必要があるなど)を維持したい場合は、頑張ってください。世界中のどの国でも将来いつでも時代遅れになる可能性のある複雑なルールセットを維持することは、面白そうに聞こえません。

そして、すべて/ほとんどの非数値文字を取り除くことはサーバー側でうまくいくかもしれませんが(特に、これらの値をダイヤラーに渡すことを計画している場合)、検証中にユーザーの入力をスラッシュしたくない場合、特に別のフィールドで修正を行います。


22

()文字の除去は、一般的な英国の番号を書くスタイルでは機能しないことに注意してください。つまり+44 (0) 1234 567890、国際番号をダイヤルするか
+441234567890
、英国のダイヤルでダイヤルします。01234567890



12

無制限の正規表現での私の試み:

/^[+#*\(\)\[\]]*([0-9][ ext+-pw#*\(\)\[\]]*){6,45}$/

受け入れる:

+(01) 123 (456) 789 ext555
123456
*44 123-456-789 [321]
123456
123456789012345678901234567890123456789012345
*****++[](][((( 123456tteexxttppww

拒否:

mob 07777 777777
1234 567 890 after 5pm
john smith
(empty)
1234567890123456789012345678901234567890123456
911

表示のために消毒するのはあなた次第です。検証した後でも、それ数になる可能性があります。


12

これはかなりうまくいくことがわかりました:

^\(*\+*[1-9]{0,3}\)*-*[1-9]{0,3}[-. /]*\(*[2-9]\d{2}\)*[-. /]*\d{3}[-. /]*\d{4} *e*x*t*\.* *\d{0,4}$

次の数値形式で機能します。

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
1-234-567-8901 ext. 1234
(+351) 282 433 5050

確認のため、グローバルAND複数行フラグを使用してください。

リンク:http : //www.regexr.com/3bp4b


11

フォームの検証について話している場合、正しい意味と正しいデータを検証する正規表現は、国やプロバイダーの規格が異なるため、非常に複雑になります。また、最新の状態に保つことも困難になります。

私は質問を、内部的に一貫していない可能性のある広く有効なパターンを探すものとして解釈します-たとえば、有効な番号のセットを持っていますが、幹線、交換などが国コード接頭辞の有効なパターンであることを検証していません。

北米は単純明快で、国際的には、人々が番号を指定して覚える方法をカバーする「慣用的な」パターンを使用することを好みます。

^((((\(\d{3}\))|(\d{3}-))\d{3}-\d{4})|(\+?\d{2}((-| )\d{1,8}){1,5}))(( x| ext)\d{1,5}){0,1}$

北米のパターンは、1つの括弧が含まれる場合、両方が含まれることを確認します。国外では、オプションの初期「+」と国コードを使用します。その後、あなたはイディオムにいます。有効な一致は次のとおりです。

  • (xxx)xxx-xxxx
  • (xxx)-xxx-xxxx
  • (xxx)xxx-xxxx x123
  • 12 1234 123 1 x1111
  • 12 12 12 12 12
  • 12 1 1234 123456 x12345
  • +12 1234 1234
  • +12 12 12 1234
  • +12 1234 5678
  • +12 12345678

私の経験は北米、ヨーロッパ、およびアジアの一部に限定されているため、これは偏っている可能性があります。


私はJavaScript検証スクリプトに上記を実装しようとしましたが、invalid quantifierエラーが発生し続けます。私が間違っていることについてのアイデアはありますか?
Jannis、

電話が記号なしで指定されているが、おそらくスペースと国コードが指定されているという些細なケースを追加します。ヨーロッパでは、市内番号と携帯電話番号が一般的です:676412342、676 46 32
12、676

11

これは、私が達成する必要があった検証に最もよく一致した素晴らしいパターンです。私は原作者ではありませんが、この問題は非常に複雑で、簡潔で広く役立つ回答がないため、共有する価値は十分にあると思います。

次の正規表現は、さまざまなグローバル電話番号形式で広く使用されている番号と文字の組み合わせをキャッチします。

/^\s*(?:\+?(\d{1,3}))?([-. (]*(\d{3})[-. )]*)?((\d{3})[-. ]*(\d{2,4})(?:[-.x ]*(\d+))?)\s*$/gm

プラス:
+42 555.123.4567
+ 1-(800)-123-4567
+7 555 1234567
+7(926)1234567
(926)1234567
+79261234567
926 1234567
9261234567
1234567
123-4567
123-89-01
495 1234567
469 123 45 67
89261234567
8(926)1234567
926.123.4567
415-555-1234
650-555-2345
(416)555-3456
202 555 4567
4035555678
1 416 555 9292

ネガティブ:
926 3 4
8 800600-APPLE

元のソース:http : //www.regexr.com/38pvb


これは拡張機能の一部のサポートが制限されています。「616-555-1234 x567」と一致しますが、「616-555-1234 ext。567」とは一致しません。
Jon Schneider

2
たとえば、 "-------(((((55555555"または "99999999999999999999999"
mikep

Nitherland macdonalds数+31 76 596 4192(私は乱数をテストしただけです)を検証していません
BIOHAZARD

10

私の直感は、このトピックへの返信の量によって強化されています。この問題には事実上無限の数の解決策があり、どれも洗練されていません。

正直なところ、電話番号の検証は行わないことをお勧めします。さまざまな正当な形式をすべて許可する大きくて毛深いバリデーターを作成できたとしても、そもそもリモートで電話番号に似たものであればほとんど何でも許可することになります。

私の意見では、最もエレガントなソリューションは、最小の長さを検証することであり、それ以上のものはありません。


これらのいくつかを試して、既存のデータとユーザーからのフィードバックを検討した後、私は同意する傾向があります...
クリストファーキング

ただし、検証を行う必要がある場合もあります。確認コードを送信する場合、スパマーがフィールドに入力したランダムなゴミにコードを送信することはできません。メッセージを伝えるリソースを無駄にする前に、その番号がおそらく電話番号であることを確認したいと思います。
ルーク

10

これは、フィリピンの携帯電話番号の単純な正規表現パターンです。

((\+[0-9]{2})|0)[.\- ]?9[0-9]{2}[.\- ]?[0-9]{3}[.\- ]?[0-9]{4}

または

((\+63)|0)[.\- ]?9[0-9]{2}[.\- ]?[0-9]{3}[.\- ]?[0-9]{4}

これらと一致します:

+63.917.123.4567  
+63-917-123-4567  
+63 917 123 4567  
+639171234567  
09171234567  

最初のものは2桁の国コードに一致し、2番目のものはフィリピンの国コードにのみ一致します。

ここでテストしてください:http : //refiddle.com/1ox


ありがとう。028231234などの市外局番の固定電話番号はどうですか?市外局番は2〜3桁の数字で、常に0が前に付いているのでしょうか。
stormwild 2014

9

ここまでが私の最善の努力です。上記のフォーマットを処理しますが、他のいくつかの可能なフォーマットがないと確信しています。

^\d?(?:(?:[\+]?(?:[\d]{1,3}(?:[ ]+|[\-.])))?[(]?(?:[\d]{3})[\-/)]?(?:[ ]+)?)?(?:[a-zA-Z2-9][a-zA-Z0-9 \-.]{6,})(?:(?:[ ]+|[xX]|(i:ext[\.]?)){1,2}(?:[\d]{1,5}))?$

9

あなたは単一/単純な正規表現で国際番号を扱うのに苦労するでしょう、国際(さらには北米)の電話番号の難しさに関するこの投稿を見てください。

最初の数桁を解析して国コードを特定し、国に基づいて異なる動作をさせる必要があります。

それを超えて-あなたが与えたリストには別の一般的な米国の形式は含まれていません-最初の1を省いてください。米国のほとんどの携帯電話はそれを必要とせず、国際的にダイヤルしない限り若い世代を困惑させ始めます。

あなたはそれがトリッキーな問題であることを正しく識別しました...

-アダム


提供されたソリューションではありません。可能です。トリッキーまたは複雑だからといって、腕を上げるだけでは意味がありません。
Eric Hodonsky 2017年

7

これらの回答を読んだ後、一連のテキストを解析し、電話番号を任意の形式(国際電話とプラス記号なしの国際電話番号を含む)で取り出すことができる簡単な正規表現はなかったようです。

これが最近クライアントプロジェクトで使用したもので、あらゆる形式のすべての電話番号をtel:リンクに変換する必要がありました。

これまでのところ、彼らが投げたすべてのもので機能していますが、エラーが発生した場合は、この回答を更新します。

正規表現:

/(\+*\d{1,})*([ |\(])*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4})/

すべての電話番号をtel:リンクに置き換えるPHP関数(誰かが興味がある場合):

function phoneToTel($number) {
    $return = preg_replace('/(\+*\d{1,})*([ |\(])*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4})/', '<a href="tel:$1$3$4$5">$1 ($3) $4-$5</a>', $number); // includes international
    return $return;
}

この正規表現は一致しました+1 1234562222222222222222222222
VardaElentári、2015年

なぜただ戻るのではないのですか?
thexande 2017年

「999999999999999999999999999999999999999」の誤検知
Ben Wheeler

6

私は信じている番号::電話::米国および正規表現を::一般的な (特にソース正規表現::共通:: URI :: RFC2806)Perlモジュールは助けることができます。

質問は、数値を検証する目的を説明するために、おそらくもう少し詳しく指定する必要があります。たとえば、911は米国では有効な数値ですが、911xはxの値としては無効です。これは、ダイヤルが完了したときに電話会社が計算できるようにするためです。この問題にはいくつかのバリエーションがあります。しかし、あなたの正規表現は市外局番の部分をチェックしないので、それは問題ではないようです。

電子メールアドレスの検証と同様に、有効な結果が得られたとしても、実際に試してみるまでは、それが誰かに割り当てられているかどうかはわかりません。

ユーザー入力を検証しようとしている場合は、結果を正規化してそれを使ってみませんか?ユーザーが有効な番号として認識できない番号を入力した場合は、入力した番号として保存するか、使用できない文字を削除します。番号::電話::ノーマライズ Perlモジュールは、インスピレーションの源である可能性があります。


ここで外に出て、911を電話番号として許可することは、この正規表現のほとんどすべてのアプリケーションでおそらく悪い考えだと言います。いいキャッチ。
ニコラスフリント2012

4

私は市場調査会社で働いており、これらのタイプの入力をすべてフィルター処理する必要があります。複雑すぎます。英数字以外の文字を削除し、拡張子があるかどうかを確認します。

さらに分析するには、有効な番号のデータベースへのアクセスを提供する多くのプロバイダーの1つにサブスクライブし、それらが固定電話または携帯電話であるか、切断されているかなどを通知できます。コストがかかります。


検証?123パーセントの$)*%()$ *()#456 *()* $#(*(8908 @#$はあなたの提案されたソリューションにマッチします。
PlexQ

1
@PlexQ 555-123-1234、07777777777、90210、01 / 01/1901-検証を通じてゴミを詰め込むことにユーザーは進歩的です。過度に制限された検証を使用して、それらが間違っていることを告げることによって、本当に奇妙なデータを持っている人をチェックオフしない方が良いでしょう。
ReactiveRaven

4

フォーマット文字を置き換えてから、残りの電話の有効性を確認します。PHPでは、

 $replace = array( ' ', '-', '/', '(', ')', ',', '.' ); //etc; as needed
 preg_match( '/1?[0-9]{10}((ext|x)[0-9]{1,4})?/i', str_replace( $replace, '', $phone_num );

このような複雑な正規表現を破ることは、同じくらい効果的ですが、はるかに簡単です。


3

これは面白いものだと思いました。私はテストしていませんが、うまくいくように見えます

<?php
/*
string validate_telephone_number (string $number, array $formats)
*/

function validate_telephone_number($number, $formats)
{
$format = trim(ereg_replace("[0-9]", "#", $number));

return (in_array($format, $formats)) ? true : false;
}

/* Usage Examples */

// List of possible formats: You can add new formats or modify the existing ones

$formats = array('###-###-####', '####-###-###',
                 '(###) ###-###', '####-####-####',
                 '##-###-####-####', '####-####', '###-###-###',
                 '#####-###-###', '##########');

$number = '08008-555-555';

if(validate_telephone_number($number, $formats))
{
echo $number.' is a valid phone number.';
}

echo "<br />";

$number = '123-555-555';

if(validate_telephone_number($number, $formats))
{
echo $number.' is a valid phone number.';
}

echo "<br />";

$number = '1800-1234-5678';

if(validate_telephone_number($number, $formats))
{
echo $number.' is a valid phone number.';
}

echo "<br />";

$number = '(800) 555-123';

if(validate_telephone_number($number, $formats))
{
echo $number.' is a valid phone number.';
}

echo "<br />";

$number = '1234567890';

if(validate_telephone_number($number, $formats))
{
echo $number.' is a valid phone number.';
}
?>

4
このメッセージは、このコードを記述していないことを示しているようです。出典を引用していただけませんか?
Alastair Irvine


3

おそらく、マスクされた入力を使用するほうがよいでしょう。これにより、ユーザーは数値のみを入力でき、必要に応じて書式を設定できます。これがWebアプリケーション用かどうかはわかりませんが、これがある場合、これを実行するためのいくつかのオプションを提供する非常にクリックしやすいjQueryプラグインがあります。

http://digitalbush.com/projects/masked-input-plugin/

チュートリアルでは、電話番号の入力をマスクする方法についても説明しています。


3

これはJavaScriptでうまく機能するものです。それはDojoウィジェットが期待していたものであるため、文字列の中にあります。

オプションの内線番号付きの10桁の北米NANP番号と一致します。スペース、ダッシュ、ピリオドは区切り文字として使用できます。

"^(\\(?\\d\\d\\d\\)?)( |-|\\.)?\\d\\d\\d( |-|\\.)?\\d{4,4}(( |-|\\.)?[ext\\.]+ ?\\d+)?$"

3

私は同じ問題に苦労して、アプリケーションを将来を見据えたものにしようとしましたが、これらの人たちは私を正しい方向に導いてくれました。実際に番号自体をチェックして機能するかどうかを確認するのではなく、単に内線番号があるかどうかに関係なく、一連の番号が入力されていることを確認しようとしています。

最悪の場合、ユーザーがXMLファイルからフォーマットされていない番号を取得012345678x5する必要がある場合でも、番号を電話のテンキーに入力するだけで、番号をそのままにしておく理由はありません。この種のRegExは、私にとって次のようなものになります。

\d+ ?\w{0,9} ?\d+
  • 01234467 extension 123456
  • 01234567x123456
  • 01234567890

2

私の傾向は、非数字を取り除き、そこにあるものだけを受け入れるのが最善であることに同意することです。たぶん、少なくとも2桁あることを確認する必要がありますが、たとえば、アルファベットの電話番号「ASK-JAKE」のようなものは禁止されています。

いくつかの単純なperl式は次のようになります。

@f = /(\d+)/g;
tr/0-9//dc;

最初のものを使用して、桁グループをまとめます。これにより、フォーマットの手がかりが得られる場合があります。2番目のものを使用して、すべての非数字を簡単にトスします。

一時停止してからさらにキーを入力する必要があるのではないかと心配ですか?または555-1212(ビープ音を待つ)123のようなものですか?


2
    pattern="^[\d|\+|\(]+[\)|\d|\s|-]*[\d]$" 
    validateat="onsubmit"

数字で終わる必要があり、(または+または数字で始まることができ、+-(または)を含めることができます


2

アイルランドの携帯電話番号で同じようなことをすることに興味がある人のために、それを達成する簡単な方法は次のとおりです:

http://ilovenicii.com/?p=87

PHP


<?php
$pattern = "/^(083|086|085|086|087)\d{7}$/";
$phone = "087343266";

if (preg_match($pattern,$phone)) echo "Match";
else echo "Not match";

そのリンクにはJQueryソリューションもあります。

編集:

jQueryソリューション:

    $(function(){
    //original field values
    var field_values = {
            //id        :  value
            'url'       : 'url',
            'yourname'  : 'yourname',
            'email'     : 'email',
            'phone'     : 'phone'
    };

        var url =$("input#url").val();
        var yourname =$("input#yourname").val();
        var email =$("input#email").val();
        var phone =$("input#phone").val();


    //inputfocus
    $('input#url').inputfocus({ value: field_values['url'] });
    $('input#yourname').inputfocus({ value: field_values['yourname'] });
    $('input#email').inputfocus({ value: field_values['email'] }); 
    $('input#phone').inputfocus({ value: field_values['phone'] });



    //reset progress bar
    $('#progress').css('width','0');
    $('#progress_text').html('0% Complete');

    //first_step
    $('form').submit(function(){ return false; });
    $('#submit_first').click(function(){
        //remove classes
        $('#first_step input').removeClass('error').removeClass('valid');

        //ckeck if inputs aren't empty
        var fields = $('#first_step input[type=text]');
        var error = 0;
        fields.each(function(){
            var value = $(this).val();
            if( value.length<12 || value==field_values[$(this).attr('id')] ) {
                $(this).addClass('error');
                $(this).effect("shake", { times:3 }, 50);

                error++;
            } else {
                $(this).addClass('valid');
            }
        });        

        if(!error) {
            if( $('#password').val() != $('#cpassword').val() ) {
                    $('#first_step input[type=password]').each(function(){
                        $(this).removeClass('valid').addClass('error');
                        $(this).effect("shake", { times:3 }, 50);
                    });

                    return false;
            } else {   
                //update progress bar
                $('#progress_text').html('33% Complete');
                $('#progress').css('width','113px');

                //slide steps
                $('#first_step').slideUp();
                $('#second_step').slideDown();     
            }               
        } else return false;
    });

    //second section
    $('#submit_second').click(function(){
        //remove classes
        $('#second_step input').removeClass('error').removeClass('valid');

        var emailPattern = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;  
        var fields = $('#second_step input[type=text]');
        var error = 0;
        fields.each(function(){
            var value = $(this).val();
            if( value.length<1 || value==field_values[$(this).attr('id')] || ( $(this).attr('id')=='email' && !emailPattern.test(value) ) ) {
                $(this).addClass('error');
                $(this).effect("shake", { times:3 }, 50);

                error++;
            } else {
                $(this).addClass('valid');
            }


        function validatePhone(phone) {
        var a = document.getElementById(phone).value;
        var filter = /^[0-9-+]+$/;
            if (filter.test(a)) {
                return true;
            }
            else {
                return false;
            }
        }

        $('#phone').blur(function(e) {
            if (validatePhone('txtPhone')) {
                $('#spnPhoneStatus').html('Valid');
                $('#spnPhoneStatus').css('color', 'green');
            }
            else {
                $('#spnPhoneStatus').html('Invalid');
            $('#spnPhoneStatus').css('color', 'red');
            }
        });

     });

        if(!error) {
                //update progress bar
                $('#progress_text').html('66% Complete');
                $('#progress').css('width','226px');

                //slide steps
                $('#second_step').slideUp();
                $('#fourth_step').slideDown();     
        } else return false;

    });


    $('#submit_second').click(function(){
        //update progress bar
        $('#progress_text').html('100% Complete');
        $('#progress').css('width','339px');

        //prepare the fourth step
        var fields = new Array(
            $('#url').val(),
            $('#yourname').val(),
            $('#email').val(),
            $('#phone').val()

        );
        var tr = $('#fourth_step tr');
        tr.each(function(){
            //alert( fields[$(this).index()] )
            $(this).children('td:nth-child(2)').html(fields[$(this).index()]);
        });

        //slide steps
        $('#third_step').slideUp();
        $('#fourth_step').slideDown();            
    });


    $('#submit_fourth').click(function(){

        url =$("input#url").val();
        yourname =$("input#yourname").val();
        email =$("input#email").val();
        phone =$("input#phone").val();

        //send information to server
        var dataString = 'url='+ url + '&yourname=' + yourname + '&email=' + email + '&phone=' + phone;  



        alert (dataString);//return false;  
            $.ajax({  
                type: "POST",  
                url: "http://clients.socialnetworkingsolutions.com/infobox/contact/",  
                data: "url="+url+"&yourname="+yourname+"&email="+email+'&phone=' + phone,
                cache: false,
                success: function(data) {  
                    console.log("form submitted");
                    alert("success");
                }
                });  
        return false;

   });


    //back button
    $('.back').click(function(){
        var container = $(this).parent('div'),
        previous  = container.prev();

        switch(previous.attr('id')) {
            case 'first_step' : $('#progress_text').html('0% Complete');
                  $('#progress').css('width','0px');
                       break;
            case 'second_step': $('#progress_text').html('33% Complete');
                  $('#progress').css('width','113px');
                       break;

            case 'third_step' : $('#progress_text').html('66% Complete');
                  $('#progress').css('width','226px');
                       break;

        default: break;
    }

    $(container).slideUp();
    $(previous).slideDown();
});


});

ソース

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.