タイトル通りによく使う正規表現を毎回ググるのが効率悪いのでまとめてみました。各言語で正規表現のサンプルを書いてみました。

正規表現式

  • Emailアドレス
    ^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$

  • ドメイン名
    ^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]\.[a-zA-Z]{2,}$

  • インタネットURL
    ^(http|https)://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$

  • ユーザー名 (Twitter username)
    ^[a-zA-Z0-9_\-.]{3,15}$

  • 固定電話
    ^0\d-\d{4}-\d{4}$

  • 携帯電話
    ^(070|080|090)-\d{4}-\d{4}$

  • IP電話
    ^050-\d{4}-\d{4}$

  • フリーダイヤル
    ^0120-\d{3}-\d{3}$

  • パスワード(大文字小文字英数字組み合わせ、特殊文字禁止、長さは8-10
    ^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$

  • 日付 (YYYY-MM-DD)
    ^\d{4}-\d{1,2}-\d{1,2}$

  • 郵便番号
    ^\d{3}-\d{4}$

  • XML
    ^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$

  • 空白行
    \n\s*\r

  • 先頭後尾空白文字
    ^\s*|\s*$

  • IPアドレス
    \d+\.\d+\.\d+\.\d+

  • IPアドレス
    ((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))

  • 数字
    ^[0-9]*$

  • N桁数字
    ^\d{n}$

  • N桁以下数字
    ^\d{n,}$

  • M-N桁数字
    ^\d{m,n}$

  • ゼロから始まる数字
    ^(0[0-9]*)$

  • ゼロ以外から始まる数字
    ^([1-9][0-9]*)$

  • 小数点以下1-2位数字
    ^(\-)?\d+(\.\d{1,2})?$

  • 正整数
    ^[1-9]\d*$

  • 負整数
    ^\-[1-9]\d*$

  • 英数字
    ^[A-Za-z0-9]+$

  • 長さが3-20の全ての文字
    ^.{3,20}$

  • 大文字小文字26英字
    ^[A-Za-z]+$

  • 大文字26英字
    ^[A-Z]+$

  • 小文字26英字
    ^[a-z]+$

言語別

Go

package main

import (
    "fmt"
    "regexp"
)

func main() {
    rep := regexp.MustCompile(`^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$`)
    isEmail := rep.MatchString("dongri@qiita.com")
    fmt.Println(isEmail) // true | false
}

Ruby

#!/usr/bin/env ruby

rep = Regexp.new("^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$")
isEmail = rep === "dongri@qiita.com"
puts isEmail

JavaScript


var regex = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
regex.test("dongri@qiita.com"); // true | false

var regex = new RegExp('^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$');
regex.test("dongri@qiita.com"); // true | false

Perl


#!/usr/bin/env perl

$rep = '^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$';
$email = 'dongri.@qiita.com';
if ($email =~ /$rep/) {
    print "valid";
} else {
    print "invalid";
}

Python

#!/usr/bin/env python

import re

rep = '^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$';
email = 'dongri@qiita.com';
isEmail = re.match(rep, email) != None;

print(isEmail);

Swift


import Foundation

let rep = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$"
let email = "dongri@qiita.com"
let isEmail = NSPredicate(format: "SELF MATCHES %@", rep).evaluate(with: email)

print(isEmail)

Java

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {
    public static void main(String[] args) {
        String regex = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$";
        String email = "dongri@qiita.com";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(email);
        Boolean isEmail = matcher.matches();

        System.out.println(isEmail);
    }
}

追記

想像以上にバズってツッコミ満載ですが、この記事の目的は弊社がこれらを使ってる、これらが一番良い式ではなく、あくまで一例を示してます。みなさんもおわかりかと思いますが、正規表現は効率良い、悪い、キレイ、汚いいろんな書き方もあれば要件によって100%汎用なものを作って毎回それを使うのは無理かと思います。基本的なベースがあれば、そこにちょっと手を入れてチューニングすれば自分達が必要な式を求められるんじゃないかと思います。そのようなニュアンスで書いたサンプルようなものでした。

Like, Stockしてる方々も参考になれると思いますので。引き続きツッコミお願いします。

3905contribution

「英数字」と「大文字小文字26英字+数字」は同じ意味でしょうか。

901contribution

@7of9 失礼しました。同じ意味でした。下の方削除します。 :thumbsup:

2720contribution

Ruby の場合,

Regexp.new("云々")

などと書かなくても正規表現リテラルがあるので,

/云々/

と書けます。
この書き方だと,正規表現がバックスラッシュを含む場合に,

Regexp.new("\\d")

などと面倒なエスケープをせずに

/\d/

と書けます。

なお,

rep === "dongri@qiita.com"

という書き方は何の問題もありませんが,===case 式や grep などで暗黙に呼ばれるメソッドというテイスト(?)なので,

rep =~ "dongri@qiita.com"

という書き方のほうをお勧めします。

また,非常に大事なことですが,Ruby の ^, $文字列の先頭・末尾ではなく行頭・行末です。
従って,たとえば str が数字のみからなっていることを確認しようとして

/^[0-9]+$/ =~ str

と書いてはいけません。str"abc\n123\ndef" のような場合でも真になってしまいます。
この手のバグは極めて深刻なセキュリティー上の問題につながる恐れがあります。

以上が Ruby についてですが,正規表現の内容についても気になるところがちらほらあります。
たとえば固定電話が

 ^0\d-\d{4}-\d{4}$

となっていますが,市外局番は最大 4 桁ですよね。
(市外局番は 0 を除いた部分を指すようです。03 の 0 はプレフィクスで,市外局番の一部ではないんですね。いま知りました)

218contribution

Rubyときなのですが、
@scivola さんの言うように

/云々/

もできますし、以下のように%rを使って書くこともできます。

%r{云々} 
%r<云々> 

%rの利点は/などをエスペケープせずに使えるので、URLを以下のように書けるようになることです。

%r{^(http|https)://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$}
464contribution

正規表現を使うべきか?は常に考えたほうが良いですね。
正規表現を正しく理解できないことによる、
脆弱性、処理効率、可読性の悪さなど、あまり人におすすめできる道具ではないです。
私自身は正規表現が大好きですけど・・・。

例で見れば、

  • パスワード: ANDチェックは基本的に正規表現向きでない(流石に10桁上限はネタとしても)
  • IPアドレス: 数値の上限下限も正規表現向きでない

なんかは、正規表現でやらんでも、という感じです。

だいぶ懐かしいページではありますが、
http://www.din.or.jp/~ohzaki/mail_regex.htm とか
http://www.din.or.jp/~ohzaki/perl.htm#httpURL とか読むとタノシイですよ。
Perl互換の正規表現で闇に飲まれる感じがたまりません

21contribution

0800-xxx-xxxのフリーダイヤルはの固定電話^0\d-\d{4}-\d{4}$にもフリーダイヤル^0120-\d{3}-\d{3}$にも該当しなくて使えませんよね。
少なくとも東京大阪以外と千葉埼玉の一部以外にヒットしない固定電話は実用に耐えないと思いますが……

あとは空白行チェックの\n\s*\rもCRLFでしか使えないのでどうかと思います。

10contribution

ruby版で、"<script>alert(1)</script>\ndongri@qiita.com" を判定させると true になりますね。これは脆弱性と言ってよいレベルではないでしょうか? (バリデーションだけでXSS対策するのはよくありませんが、それはそれとして)


既出でしたね。失礼しました。なお、$はRubyの場合に、より顕著ですが、他の言語でも使わない方がよいです。
https://blog.tokumaru.org/2014/03/z.html

(070|080|090)0[789]0の方が短く分かりやすいのではないでしょうか

21contribution

数字などで*を使用すると空文字も検出されるので
+を使用したほうが良いかと。
reg_number.png

901contribution

異常に反応が多かったので、本文に追記しました。

みなさん、いろんなツッコミありがとうございます!
引き続きよろしくお願いします。

0contribution

Pythonの例についてちょっと申し上げます。一般的には

import re

rep = r'^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$'
email = 'dongri@qiita.com'
is_email = re.match(rep, email) is not None

print(is_email)

と書けます。元の例文との相違点について:

  1. repのリテラルはr-stringにする。これは\s\nのようなエスケープシーケンスを回避できるで便利です。
  2. Pythonの標準スタイルガイドのPEP 8によって、Noneとのコンペアはisis notにする。
  3. 同じくPEP 8によって行末のセミコロンは要りません。

また、同じパターンを複数回使用するときに、こうやってリソース節約出来ます:

import re

regex = re.compile(r'^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$')
emails = ['dongri@qiita.com', 'me@example.com']
for email in emails:
    is_email = regex.match(email) is not None
    print(is_email)

差し出がましいようですが失礼しました。

0contribution

This is really good one.Thank you for sharing this.Payroll software Dubai appreciate you for providing the examples in different languages thus useful for everyone.