知っておくべき正規表現 - 一般的な問題に対する正規表現による解決策

目次

1. 北米の電話番号

2. アメリカの ZIP エンコーディング

3. カナダの郵便番号

4. イギリスの郵便番号

5. 米国の社会保障番号

6. IPアドレス

7. URL

8. 完全な URL

9. メールアドレス

10. HTMLコメント

11. JavaScriptのコメント

12. クレジットカード番号


        正規表現に関する質問に最終的な答えがあることはほとんどありません。多くの場合、それは不確実性に対する許容度に依存します。解決策は複数あり、正規表現のパフォーマンスと処理できるシナリオの間には常にトレードオフがあります。条件を満たす数値を照合するだけでなく、条件を満たさない数値を除外する必要があるため、この正規表現が複雑に見えることに注意してください。

1. 北米の電話番号

        北米番号計画は、北米の電話番号の形式を定義します。このスキームでは、北米 (米国、カナダ、カリブ海のほとんどの地域、およびその他のいくつかの地域) の電話番号は 3 桁の市外局番と 7 桁の番号で構成されます。この7桁の番号は、3桁の局番と4桁の回線番号に分かれており、局番と回線番号はハイフンで区切られています。各電話番号には任意の番号を指定できますが、市外局番と局番の最初の桁を 0 または 1 にすることはできません。市外局番は多くの場合括弧内に置かれ、市外局番と実際の電話番号の間にハイフンが追加されて区切られます。次の 4 つの形式のみが正当であると仮定します:
(555) 555-5555
(555)555-5555
555-555-5555
555.555.5555

mysql> set @s:='J. Doe: 248-555-1234
    '> B. Smith: (313) 555-1234
    '> A. Lee: (810)555-1234
    '> M. Jones: 734.555.9999';
Query OK, 0 rows affected (0.00 sec)

mysql> set @r:='(\\([2-9]\\d{2}\\)\\s?\\d{3}-\\d{4})|([2-9]\\d{2}(?<z>[.-]))\\d{3}\\k<z>\\d{4}';
Query OK, 0 rows affected (0.00 sec)

mysql> select regexp_count(@s, @r, '') c, regexp_extract(@s, @r, '') s, regexp_extract_index(@s, @r, 0, '') i;
+------+--------------------------------------------------------+------------+
| c    | s                                                      | i          |
+------+--------------------------------------------------------+------------+
|    4 | 248-555-1234,(313) 555-1234,(810)555-1234,734.555.9999 | 9,32,55,79 |
+------+--------------------------------------------------------+------------+
1 row in set (0.01 sec)

2. アメリカの ZIP エンコーディング

        米国は 1963 年に ZIP エンコードの使用を開始しました (ZIP、Zone Improvement Plan の頭字語)。現在、米国には 40,000 以上の郵便番号があり、すべて数字で構成されています (最初の桁は米国の東から西までの地域を表し、0 は東海岸地域を表し、9 は西部を表します)海岸地域)。1983 年に、米国郵便公社は Extended ZIP (略して ZIP+4) の使用を開始しました。新たに追加された4桁の番号により、手紙の配達エリアがより詳細に(特定の街区または特定の建物まで)分割され、手紙の配達の効率と精度が大幅に向上します。ただし、ZIP+4 エンコードの使用はオプションであるため、ZIP エンコードを確認するには、通常、5 桁の ZIP エンコードと 9 桁の ZIP+4 エンコードの両方、および ZIP+4 エンコードの最後の 4 桁を考慮する必要があります。最初の 5 桁はハイフンで区切ります。

mysql> set @S:='999 1st Avenue, Bigtown, NY, 11222
    '> 123 High Street, Any City, MI 48034-1234';
Query OK, 0 rows affected (0.00 sec)

mysql> set @r:='\\d{5}(-\\d{4})?';
Query OK, 0 rows affected (0.00 sec)

mysql> select regexp_count(@s, @r, '') c, regexp_extract(@s, @r, '') s, regexp_extract_index(@s, @r, 0, '') i;
+------+------------------+-------+
| c    | s                | i     |
+------+------------------+-------+
|    2 | 11222,48034-1234 | 30,66 |
+------+------------------+-------+
1 row in set (0.00 sec)

        \d{5} は任意の 5 桁の数字に一致し、-\d{4} はハイフンと最後の 4 桁に一致します。最後の 4 桁はオプションであるため、-\d{4} をかっこで囲んで部分式にし、? を使用してこの部分式が最大 1 回のみ出現できることを示します。

3. カナダの郵便番号

        カナダの郵便番号は、6 文字の交互の英数字で構成されます。各コードは 2 つの部分に分かれています。最初の 3 文字は FSA (前方仕分けエリア) コードを示し、最後の 3 文字は LDU (ローカル配送単位) コードを示します。FSA コードの最初の文字は、州、市、または地域を示すために使用されます。この文字には、ニューファンドランドの A、ノバスコシアの B、オンタリオの K、L、N、P、トロントの M など、18 の有効な選択肢があります。スキーマはこれに対して検証して、この文字の有効性を確認する必要があります。カナダの郵便番号を記述する場合、通常、FSA コードと LDU コードはスペースで区切られます。

mysql> set @s:='123 4th Street, Toronto, Ontario, M1A 1A1
    '> 567 8th Avenue, Montreal, Quebec, H9Z 9Z9';
Query OK, 0 rows affected (0.00 sec)

mysql> set @r:='[ABCEGHJKLMNPRSTVXY]\\d[A-Z] \\d[A-Z]\\d';
Query OK, 0 rows affected (0.00 sec)

mysql> select regexp_count(@s, @r, '') c, regexp_extract(@s, @r, '') s, regexp_extract_index(@s, @r, 0, '') i;
+------+-----------------+-------+
| c    | s               | i     |
+------+-----------------+-------+
|    2 | M1A 1A1,H9Z 9Z9 | 35,77 |
+------+-----------------+-------+
1 row in set (0.00 sec)

        [ABCEGHJKLMNPRSTVXY] は 18 個の有効な文字のいずれかと一致し、\d[AZ] は単一の数字とそれに続く任意の文字と一致し、これらが合わせて FSA コードと一致します。\d[AZ]\d は、任意の 2 つの数字の間の任意の文字である LDU コードと一致します。この正規表現は、大文字と小文字に関係なく、カナダの郵便番号と一致します。

4. イギリスの郵便番号

        イギリスの郵便番号は 5 ~ 7 文字の文字と数字で構成されており、これらのコードは Royal Mail によって定義されています。イギリスの郵便番号は、外側郵便番号 (または外側コード (アウトコード)) と内側郵便番号 (または内側コード (インコード)) の 2 つの部分に分かれています。外部コードは、1 ~ 2 文字の後に 1 桁または 2 桁の数字が続くか、または 1 ~ 2 文字の後に数字と文字が続くものです。内部コードは常に数字の後に 2 文字が続きます (C、I、K、M、O、V を除く文字。これら 6 文字は郵便番号には表示されません)。内側のコードと外側のコードはスペースで区切る必要があります。

mysql> set @s:='171 Kyverdale Road, London N16 6PS
    '> 33 Main Street, Portsmouth, P01 3AX
    '> 18 High Street, London NW11 8AB';
Query OK, 0 rows affected (0.00 sec)

mysql> set @r:='[A-Z]{1,2}\\d[A-Z\\d]? \\d[ABD-HJLNP-UW-Z]{2}';
Query OK, 0 rows affected (0.00 sec)

mysql> select regexp_count(@s, @r, '') c, regexp_extract(@s, @r, '') s, regexp_extract_index(@s, @r, 0, '') i;
+------+--------------------------+----------+
| c    | s                        | i        |
+------+--------------------------+----------+
|    3 | N16 6PS,P01 3AX,NW11 8AB | 28,64,95 |
+------+--------------------------+----------+
1 row in set (0.00 sec)

        このパターンでは、[AZ]{1,2}\d は 1 つまたは 2 つの文字とそれに続く数字に一致し、その後の [AZ\d]? はオプションの英字または数字に一致します。したがって、[AZ]{1,2}\d[AZ\d]? は、有効な外部コードの組み合わせに一致します。内部コード部分は \d[ABD-HJLNP-UW-Z]{2} によって照合されます。これは、内部コードで使用できる 2 つの文字が後に続く任意の数字 (A、B、D ~H、J) と照合できます。 、L、N、P〜U、W〜Z)。この正規表現は、大文字と小文字を区別せずに英国の郵便番号と一致します。

5. 米国の社会保障番号

        米国の社会保障番号 (SSN) は、ハイフンで区切られた 3 つのグループの番号で構成されます。最初のグループは 3 桁、2 番目のグループは 2 桁、3 番目のグループは 4 桁です。1972 年から、米国政府は SSN 申請者が提供した住所に基づいて最初の 3 桁の番号を割り当て始めました。

mysql> set @s:='John Smith: 123-45-6789';
Query OK, 0 rows affected (0.00 sec)

mysql> set @r:='\\d{3}-\\d{2}-\\d{4}';
Query OK, 0 rows affected (0.00 sec)

mysql> select regexp_count(@s, @r, '') c, regexp_extract(@s, @r, '') s, regexp_extract_index(@s, @r, 0, '') i;
+------+-------------+------+
| c    | s           | i    |
+------+-------------+------+
|    1 | 123-45-6789 | 13   |
+------+-------------+------+
1 row in set (0.00 sec)

        \d{3}-\d{2}-\d{4} は、任意の 3 桁、ハイフン、任意の 2 桁、ハイフン、任意の 4 桁の順序で一致します。ほとんどの番号の組み合わせは有効な SSN ですが、実際には満たす必要のある要件がいくつかあります。まず、有効な SSN にはすべてゼロのフィールドを含めることはできません。第 2 に、SSN にはそれほど大きな番号が割り当てられていないため、最初の番号セット (現時点では) が 728 を超えてはなりませんが、将来は割り当てられる可能性があります。 。ただし、これは非常に複雑なパターンになるため、通常は比較的単純な \d{3}-\d{2}-\d{4} が使用されます。

6. IPアドレス

        IP アドレスは 4 バイトで構成されます (この 4 バイトの値の範囲は 0 ~ 255)。IP アドレスは通常、. 文字で区切られた 4 つの整数グループとして記述され、各整数は 1 ~ 3 桁で構成されます。

mysql> set @s:='localhost is 127.0.0.1.';
Query OK, 0 rows affected (0.00 sec)

mysql> set @r:='(((\\d{1,2})|(1\\d{2})|(2[0-4]\\d)|(25[0-5]))\\.){3}((\\d{1,2})|(1\\d{2})|(2[0-4]\\d)|(25[0-5]))';
Query OK, 0 rows affected (0.00 sec)

mysql> select regexp_count(@s, @r, '') c, regexp_extract(@s, @r, '') s, regexp_extract_index(@s, @r, 0, '') i;
+------+-----------+------+
| c    | s         | i    |
+------+-----------+------+
|    1 | 127.0.0.1 | 14   |
+------+-----------+------+
1 row in set (0.00 sec)

        このパターンでは、一連のネストされた部分式を使用します。(((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5])\.) は 4 つのネストされた sub で表されます。式は次で構成されます: (\d{1,2}) は任意の 1 桁または 2 桁の数値 (0 ~ 99) と一致し、(1\d{2}) は 1 で始まる任意の 3 桁の数字 (100 ~ 199) と一致します。 ( 2[0-4]\d) は整数 200 ~ 249 に一致します; (25[0-5]) は整数 250 ~ 255 に一致します。これらの 4 つの部分は | 演算子によって形成されます (つまり、それらの 1 つの部分だけが | 演算子を使用する必要があります)一致する) 部分式。次の . は . 文字と一致するために使用され、前の文字とより大きな部分式を形成します。次の {3} は、それを 3 回繰り返す必要があることを示します。最後に、値の範囲がもう一度表示されます。 (今回は末尾の \. を省略して、数値の最後のグループと一致させます。4 つの数値グループすべてを 0 ~ 255 の範囲に制限することにより、このパターンは有効な IP アドレスのみに正確に一致し、無効な IP は除外されます。

7. URL

        URL の一致は困難な作業であり、その複雑さは一致がどの程度正確に求められるかによって異なります。URL 一致パターンは、少なくともプロトコル (http または https)、ホスト名、オプションのポート番号、およびパスと一致する必要があります。

mysql> set @s:='http://www.forta.com/blog
    '> https://www.forta.com:80/blog/index.cfm
    '> http://www.forta.com
    '> http://ben:[email protected]/
    '> http://localhost/index.php?ab=1&c=2
    '> http://localhost:8500/';
Query OK, 0 rows affected (0.00 sec)

mysql> set @r:='https?:\\/\\/[-\\w.]+(:\\d+)?(\\/([\\w\\/_.]*)?)?';
Query OK, 0 rows affected (0.00 sec)

mysql> select regexp_count(@s, @r, '') c, regexp_extract(@s, @r, '') s, regexp_extract_index(@s, @r, 0, '') i;
+------+-----------------------------------------------------------------------------------------------------------------------------------------------------+--------------------+
| c    | s                                                                                                                                                   | i                  |
+------+-----------------------------------------------------------------------------------------------------------------------------------------------------+--------------------+
|    6 | http://www.forta.com/blog,https://www.forta.com:80/blog/index.cfm,http://www.forta.com,http://ben,http://localhost/index.php,http://localhost:8500/ | 1,27,67,88,123,159 |
+------+-----------------------------------------------------------------------------------------------------------------------------------------------------+--------------------+
1 row in set (0.01 sec)

        https?:\/\/ は http:// または https:// に一致し、? により文字 s がオプションになります。[-\w.]+ はホスト名と一致します。(:\d+)? は、オプションのポート番号と一致します。(\/([\w\/_.]*)?)? パスの一致: 外側の部分式は / (存在する場合) と一致し、内側の部分式はパス自体と一致します。ご覧のとおり、このモードではクエリ文字列を処理できず、URL に埋め込まれた「ユーザー名:パスワード」を正しく解釈することもできません。ただし、ほとんどの URL (ホスト名、ポート番号、パスが一致するもの) を処理するには十分です。URL と一致するこの正規表現では、大文字と小文字が区別されません。

        FTP プロトコルを使用する URL も照合する場合は、https? を (http|https|ftp) に置き換えます。他のプロトコルを使用する URL も同様の方法で照合できます。

8. 完全な URL

        ここでは、より完全な (そして遅い) URL 照合パターンを示します。これは、URL クエリ文字列 (URL に埋め込まれている、? で URL 内のアドレスと区切られた可変情報) とオプションのユーザー ログイン情報も照合できます。

mysql> set @s:='http://www.forta.com/blog
    '> https://www.forta.com:80/blog/index.cfm
    '> http://www.forta.com
    '> http://ben:[email protected]/
    '> http://localhost/index.php?ab=1&c=2
    '> http://localhost:8500/';
Query OK, 0 rows affected (0.00 sec)

mysql> set @r:='https?:\\/\\/(\\w*:\\w*@)?[-\\w.]+(:\\d+)?(\\/([\\w\\/_.]*(\\?\\S+)?)?)?';
Query OK, 0 rows affected (0.00 sec)

mysql> select regexp_count(@s, @r, '') c, regexp_extract(@s, @r, '') s, regexp_extract_index(@s, @r, 0, '') i;
+------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------+
| c    | s                                                                                                                                                                                    | i                  |
+------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------+
|    6 | http://www.forta.com/blog,https://www.forta.com:80/blog/index.cfm,http://www.forta.com,http://ben:[email protected]/,http://localhost/index.php?ab=1&c=2,http://localhost:8500/ | 1,27,67,88,123,159 |
+------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------+
1 row in set (0.02 sec)

        このパターンは、前の例を改良したものです。今回は https?: \/\/ の後に (\w*:\w*@)? が続き、これは URL に埋め込まれたユーザー名とパスワードと一致します (ユーザー名とパスワードは: で区切られ、その後に @ が続きます)文字)、この例の 4 行目を参照してください。さらに、パスの後の (\?\S+)? はクエリ文字列との一致を担当し、? の後に表示されるテキストはオプションであり、? で表すことができます。URL と一致するこの正規表現では、大文字と小文字が区別されません。前のパターンの代わりにこのパターンを使用してみてはいかがでしょうか? パフォーマンスの点では、パターンが複雑になればなるほど、実行速度が遅くなります。余分な機能が必要ない場合は、使用しないほうがよいでしょう。

9. メールアドレス

        正規表現は電子メール アドレスの検証によく使用されますが、単純な電子メール アドレスであっても検証が困難な場合があります。

mysql> set @s:='My name is Ben Forta, and my
    '> email address is [email protected].';
Query OK, 0 rows affected (0.00 sec)

mysql> set @r:='(\\w+\\.)*\\w+@(\\w+\\.)+[A-Za-z]+';
Query OK, 0 rows affected (0.00 sec)

mysql> select regexp_count(@s, @r, '') c, regexp_extract(@s, @r, '') s, regexp_extract_index(@s, @r, 0, '') i;
+------+---------------+------+
| c    | s             | i    |
+------+---------------+------+
|    1 | [email protected] | 47   |
+------+---------------+------+
1 row in set (0.00 sec)

        (\w+\.)*\w+ は、電子メール アドレスのユーザー名部分 (@ より前のすべて) に一致します。 (\w+\.)* は、その後に .,\w+ が続くゼロ個以上のテキストに一致します。 必須のテキストに一致します (例:この組み合わせは ben と ben.forta に一致します)。次に、@ は @ 文字自体と一致します。(\w+\.)+ は . で終わる少なくとも 1 つの文字列と一致し、[A-Za-z]+ はトップレベル ドメイン名 (com、edu、us、uk など) と一致します。電子メール アドレス形式の有効性を決定するルールは非常に複雑です。このモードでは、考えられるすべての電子メール アドレスを検証することはできません。たとえば、このモードでは、[email protected] が有効であると見なされ (明らかに無効です)、IP アドレスをホスト名の一部として使用することは許可されません (これは問題ありません)。繰り返しますが、ほとんどの電子メール アドレスを確認するには十分なので、引き続き使用できます。電子メール アドレスと一致するこの正規表現では、大文字と小文字が区別されません。

10. HTMLコメント

        HTML ページ内のコメントは、<!-- タグと --> タグの間に配置する必要があります。どちらのタグにも少なくとも 2 つのハイフンが含まれている必要がありますが、2 つ以上であっても問題ありません。Web ページを閲覧 (またはデバッグ) するとき、すべてのコメントを見つけると便利です。

mysql> set @s:='<!-- Start of page -->
    '> <html>
    '> <!-- Start of head -->
    '> <head>
    '> <title>My Title</title> <!-- Page title -->
    '> </head>
    '> <!-- Body -->
    '> <body>';
Query OK, 0 rows affected (0.00 sec)

mysql> set @r:='<!(-{2,}).*?[^-]\\1>';
Query OK, 0 rows affected (0.00 sec)

mysql> select regexp_count(@s, @r, '') c, regexp_extract(@s, @r, '') s, regexp_extract_index(@s, @r, 0, '') i;
+------+---------------------------------------------------------------------------------+-------------+
| c    | s                                                                               | i           |
+------+---------------------------------------------------------------------------------+-------------+
|    4 | <!-- Start of page -->,<!-- Start of head -->,<!-- Page title -->,<!-- Body --> | 1,31,85,113 |
+------+---------------------------------------------------------------------------------+-------------+
1 row in set (0.00 sec)

        <!-{2,} は、HTML コメントの開始タグ、つまり <! の後に 2 つ以上のハイフンが続くものと一致します。.*? HTML コメントのテキスト部分と一致します。ここでは遅延量指定子が使用されます。-{2,}> は、HTML コメントの終了タグと一致します。このパターンは 2 つ以上のハイフンと一致するため、開始タグと終了タグに 3 つのハイフンが含まれる CFML コメントを検索するために使用することもできます。このモードでは、HTML コメントの開始タグと終了タグのハイフンの数が一致しているかどうかもチェックされます (HTML コメントの形式が間違っているかどうかをチェックするために使用できます)。

11. JavaScriptのコメント

        JavaScript、および ActionScript や ECMAScript バリアントを含む他のスクリプト言語では、コード内のコメントは // で始まります。前の例で示したように、特定のページ上のすべてのコメントを検索すると非常に便利です。

mysql> set @s:='<script language="JavaScript">
    '> // Turn off fields used only by replace
    '> function hideReplaceFields() {
    '>   document.getElementById(\'RegExReplace\').disabled=true;
    '>   document.getElementById(\'replaceheader\').disabled=true;
    '> }
    '> // Turn on fields used only by replace
    '> function showReplaceFields() {
    '>   document.getElementById(\'RegExReplace\').disabled=false;
    '>   document.getElementById(\'replaceheader\').disabled=false;
    '> }';
Query OK, 0 rows affected (0.00 sec)

mysql> set @r:='\\/\\/.*';
Query OK, 0 rows affected (0.00 sec)

mysql> select regexp_count(@s, @r, '') c, regexp_extract(@s, @r, '') s, regexp_extract_index(@s, @r, 0, '') i;
+------+--------------------------------------------------------------------------------+--------+
| c    | s                                                                              | i      |
+------+--------------------------------------------------------------------------------+--------+
|    2 | // Turn off fields used only by replace,// Turn on fields used only by replace | 32,220 |
+------+--------------------------------------------------------------------------------+--------+
1 row in set (0.00 sec)

        パターンは単純です。\/\/.* は // に一致し、その後にコメントの内容が続きます。

12. クレジットカード番号

        正規表現ではクレジット カード番号が実際に有効であるかどうかを検証できません。最終的な結論はクレジット カード発行会社が下す必要があります。ただし、正規表現を使用すると、さらに処理する前に、1 桁多い、または 1 桁少ないなど、誤って入力されたクレジット カード番号を除外できます。

        ここで使用するパターンは、クレジット カード番号からスペースとハイフンが事前に削除されていることを前提としています。一般に、正規表現を使用してクレジット カード番号を照合する前に、クレジット カード番号から数字以外の文字を削除することをお勧めします。すべてのクレジット カードは、同じ基本的な番号付けスキームに従っています。つまり、特定の一連の番号で始まり、合計桁数が固定されています。まずはマスターカードについて見ていきましょう。

mysql> set @s:='MasterCard: 5212345678901234
    '> Visa 1: 4123456789012
    '> Visa 2: 4123456789012345
    '> Amex: 371234567890123
    '> Discover: 601112345678901234
    '> Diners Club: 38812345678901';
Query OK, 0 rows affected (0.00 sec)

mysql> set @r:='5[1-5]\\d{14}';
Query OK, 0 rows affected (0.00 sec)

mysql> select regexp_count(@s, @r, '') c, regexp_extract(@s, @r, '') s, regexp_extract_index(@s, @r, 0, '') i;
+------+------------------+------+
| c    | s                | i    |
+------+------------------+------+
|    1 | 5212345678901234 | 13   |
+------+------------------+------+
1 row in set (0.00 sec)

        MasterCard カード番号の合計の長さは 16 桁で、最初の桁は常に 5、2 番目の桁は 1 ~ 5 です。5[1-5] は最初の 2 桁に一致し、\d{14} は次の 14 桁に一致します。番号。Visa カードの状況はもう少し複雑です。

mysql> set @r:='4\\d{12}(\\d{3})?';
Query OK, 0 rows affected (0.00 sec)

mysql> select regexp_count(@s, @r, '') c, regexp_extract(@s, @r, '') s, regexp_extract_index(@s, @r, 0, '') i;
+------+--------------------------------+-------+
| c    | s                              | i     |
+------+--------------------------------+-------+
|    2 | 4123456789012,4123456789012345 | 38,60 |
+------+--------------------------------+-------+
1 row in set (0.00 sec)

        Visa カードの最初の番号は常に 4 で、全体の長さは 13 桁または 16 桁になります (14 桁または 15 桁はないため、ここでは番号範囲を使用できません)。4 は数値 4 自体に一致し、\d{12} は次の 12 桁に一致し、(\d{3})? はオプションの最後の 3 桁に一致します。American Express カード番号を照合するパターンははるかに簡単です。

mysql> set @r:='3[47]\\d{13}';
Query OK, 0 rows affected (0.00 sec)

mysql> select regexp_count(@s, @r, '') c, regexp_extract(@s, @r, '') s, regexp_extract_index(@s, @r, 0, '') i;
+------+-----------------+------+
| c    | s               | i    |
+------+-----------------+------+
|    1 | 371234567890123 | 83   |
+------+-----------------+------+
1 row in set (0.01 sec)

        American Express カード番号の合計の長さは 15 桁で、最初の 2 桁は 34 または 37 である必要があります。3[47] は最初の 2 桁に一致し、\d{13} は残りの 13 桁に一致します。Discover カード番号のパターンを一致させることも難しくありません。

mysql> set @r:='6011\\d{14}';
Query OK, 0 rows affected (0.00 sec)

mysql> select regexp_count(@s, @r, '') c, regexp_extract(@s, @r, '') s, regexp_extract_index(@s, @r, 0, '') i;
+------+--------------------+------+
| c    | s                  | i    |
+------+--------------------+------+
|    1 | 601112345678901234 | 109  |
+------+--------------------+------+
1 row in set (0.00 sec)

        Discover カード番号の合計の長さは 16 桁で、最初の 4 桁は 6011 である必要があるため、6011\d{14} を使用します。ダイナースクラブ カードの場合はもう少し複雑です。

mysql> set @r:='(30[0-5]|36\\d|38\\d)\\d{11}';
Query OK, 0 rows affected (0.00 sec)

mysql> select regexp_count(@s, @r, '') c, regexp_extract(@s, @r, '') s, regexp_extract_index(@s, @r, 0, '') i;
+------+----------------+------+
| c    | s              | i    |
+------+----------------+------+
|    1 | 38812345678901 | 141  |
+------+----------------+------+
1 row in set (0.00 sec)

        ダイナースクラブ カード番号の合計は 14 桁で、300 ~ 305、36、または 38 で始まる必要があります。最初の 3 桁が 300 ~ 305 の場合はその後に 11 桁が必要で、最初の 2 桁が 36 または 38 の場合はその後に 12 桁が必要です。ここでは比較的単純な方法が使用されています。つまり、何であっても、最初に最初の 3 桁を一致させます。(30[0-5]|36\d|38\d) には、そのうちの 1 つが一致する限り、3 つの部分式が含まれます。30[0-5] は 300 ~ 305 に一致し、36\d は任意の 3 つのうちの 36 で始まる一致します。 -数字、38\d は、38 で始まる任意の 3 桁の数字と一致します。最後に、\d{11} は残りの 11 桁と一致します。次に、上記の 5 つのクレジット カード番号の一致パターンを組み合わせるだけです。

mysql> set @r:='(5[1-5]\\d{14})|(4\\d{12}(\\d{3})?)|(3[47]\\d{13})|(6011\\d{14})|((30[0-5]|36\\d|38\\d)\\d{11})';
Query OK, 0 rows affected (0.00 sec)

mysql> select regexp_count(@s, @r, '') c, regexp_extract(@s, @r, '') s, regexp_extract_index(@s, @r, 0, '') i;
+------+---------------------------------------------------------------------------------------------------+---------------------+
| c    | s                                                                                                 | i                   |
+------+---------------------------------------------------------------------------------------------------+---------------------+
|    6 | 5212345678901234,4123456789012,4123456789012345,371234567890123,601112345678901234,38812345678901 | 13,38,60,83,109,141 |
+------+---------------------------------------------------------------------------------------------------+---------------------+
1 row in set (0.00 sec)

        このパターンは、| 演算子 (複数の選択分岐を提供します) を使用して前に取得した 5 つのパターンを結合します。これを使えば、一般的なクレジットカード5枚の番号を一度に確認することができます。ここで使用されるパターンは、クレジット カード番号の先頭の桁の順序と桁の合計の長さが正しいかどうかのみを確認できます。ただし、4 で始まる 13 桁の数字すべてが有効な Visa カード番号であるわけではありません。クレジット カード番号 (上記のすべての種類のクレジット カード) も、Mod 10 と呼ばれる数式を使用して計算され、番号が実際に有効かどうかが判断されます。Mod 10 アルゴリズムはクレジット カードの処理に不可欠な部分ですが、数学的な演算が含まれるため、正規表現のジョブではありません。

おすすめ

転載: blog.csdn.net/wzy0623/article/details/130986791