ここでは実際のケースで使えそうなものをまとめる。
メールアドレス
定義
アカウント名@ドメイン名
.+@.+
アカウント名の先頭は半角英数字
^[a-zA-Z0-9]
アカウント名のに文字目以降は半角英数字または.-_のいづれか
1文字のみの場合も考慮して*をつける
[a-zA-Z0-9.-_]*
ドメイン名の先頭は半角英数字
[a-zA-Z0-9]
ドメイン名のに文字目以降は半角英数字または.-_のいづれか
[a-zA-Z0-9.-_]+
ドメイン名は必ず.を含め、かつ.で終わらない
[a-zA-Z0-9][a-zA-Z0-9\.-_]+\.[a-zA-Z]{2,}$
これを組み合わせると、
var regexp = /^[a-zA-Z0-9][a-zA-Z0-9\.-_]*@[a-zA-Z0-9][a-zA-Z0-9\.-_]+\.[a-zA-Z]{2,}$/;
console.log(regexp.test('hoge@fuga.com'))
console.log(regexp.test('@fuga.com'))
console.log(regexp.test('_h.o.g.e@f-uga.com'))
console.log(regexp.test('ho._gr..e@fuga.com'))
console.log(regexp.test('ho._gr..e@fuga'))
console.log(regexp.test('ho._gr..e@fuga.hoge.jp'))
ただし!
メルアドについて完璧な正規表現は無いと言われている。
html5のinput[type=email]でさえ、電子メールの構文を定義するRFC5322対して意図的に違反する仕様となっている。つまり、無理ゲーってこと。
ちなみにHMTL5のinput[type=email]で動くバリデーションはこう。
^[a-zA-Z0-9\.!#$%&'*+/=?^_'{|}~-]+@[a-zA-Z0-9]+(?:\.[a-zA-Z0-9-]+)*$
実務では、HMTL5準拠のバリデーションてことで上に従えばよさそうかな。
電話番号
条件
0から始まり、10-11桁
^0\d[9,10]$
なので、
var regexp = /^0\d{9,10}$/;
console.log(regexp.test('09088883333'));
console.log(regexp.test('79088883333'));
ハイフンを含める場合は、
var regexp = /^0\d{1,3}-\d{3,4}-\d{3,4}$/;
console.log(regexp.test('79088883333'));
console.log(regexp.test('090-8888-3333'));
URL
http, httpsで始まる
:// が続く
^https?:\/\/[\w/:%#\$&\?\(\)~\.=\+\-];$
こんなかんじに。
var regexp = /^https?:\/\/[\w/:%#\$&\?\(\)~\.=\+\-]+$/;
console.log(regexp.test('http://hoge.com'))
console.log(regexp.test('https://hoge.com'))
console.log(regexp.test('//hoge.com'))
応用版
特定ドメイン(hoge.co.jp)のみマッチ
var regexp = /^https?:\/\/([\w/:%#\$&\?\(\)~\.=\+\-]+\.)?hoge\.co\.jp$/;
console.log(regexp.test('http://hoge.co.jp'))
console.log(regexp.test('http://fuga.hoge.co.jp'))
console.log(regexp.test('http://fuga.hage.co.jp'))
日付
yyyy/mm/ddの形で、うるう年等日付の妥当性は問わない
年度
\d{4}
月
月は1-12
0埋めは問わない
0?[1-9]|1[0-2]
日
日は1-31
0埋めは問わない
0?[1-9]|1[0-9]|2[0-9]|3[0-1]
又は
0?[1-9]|[12][0-9]|3[01]
まとめると、
var regexp = /^\d{4}\/(0?[1-9]|1[0-2])\/(0?[1-9]|[12][0-9]|3[01])$/;
console.log(regexp.test('2015/51/12'))
console.log(regexp.test('2015/01/12'))
console.log(regexp.test('2015/1/30'))
console.log(regexp.test('2015/1/32'))
時刻
hh:mm:ss
のフォーマットを仮定
var regexp = /^(0?[1-9]|1[1-9]|2[1-3]):(0?[1-9]|[0-5][0-9]):(0?[1-9]|[0-5][0-9])$/;
console.log(regexp.test('2015:51:12'))
console.log(regexp.test('21:11:12'))
console.log(regexp.test('21:61:12'))
console.log(regexp.test('21:61:123'))
console.log(regexp.test('21:11:23'))
console.log(regexp.test('1:1:3'))
全角文字のみ
全角文字 = 1バイト文字ではない、マルチバイト文字
こう書く
[^\x00-\x7Eァ-ン゙゚]+
\xは、16進数を検索するためのメタ文字。
\x00-\x7Eは、半角カナ以外の半各地を文字コードで範囲指定
ァ-ン゙゚は、半角カナを範囲指定
^で、真逆を指す。
var regexp = /[^\x00-\x7Eァ-ン゙゚]+/;
console.log(regexp.test('あいうえお'))
console.log(regexp.test('aiueo'))
他の方法もある。
マルチバイト文字が含まれているか。
var exp1 = /[^-~。-゚]/;
マルチバイト文字のみかどうか。
var exp2 = /^[^-~。-゚]+$/;
console.log(exp2.test('あいうeo'))
制御コードも半角カナも全部排除する場合
[^\x01-\x7E\xA1-\xDF]
HTMLタグの検索
効率よくするためには、HTMLタグの定義をある程度特定すべき。
・<>で囲まれている
・プロパティはシングル・ダブルクォートで囲まれている
<(".*?"|'.*?'|[^'"])*?>
最短マッチを使う。最短マッチとは、通常はマッチする最長もものを抽出するが、一番手前のものに変更すること。
例:hoge.jpの直後のディレクトリまでを検索。通常のままだと、最後のbarまでマッチしてしまう。
var url = 'http://hoge.jp/fuga/hoge/boo/bar'
url.match(/^http:\/\/hoge.jp\/(.*)\//);
var url = 'http://hoge.jp/fuga/hoge/boo/bar';
url.match(/^http:\/\/hoge.jp\/(.*?)\//);
後方参照
グループ化した場合、\1や\2など\nと記述することで、n番目のグループにマッチする文字列を参照することが出来る。
下の例では、\1でh1-h4のタグを参照する。
var html = '<body>' + '<h1>heading</h1>' + '<h2>heading</h2>' + '<h2>miss</h3>' + '<h3>heading</h3>' + '<h4>heading</h4>' + '</body>';
console.log(html.replace(/<(h[1-4])>.*?<\/\1>/g, ''));
下の例では、\1でtrを、\2でthまたはtdを参照している。
var html = '<table>' + '<tr></tr>' + '<tr><th>header</th></tr>' + '<tr><td>data</td></tr>' + '</table>';
console.log(html.replace(/<(tr)><(th|td)>.*?<\/\2><\/\1>/g, ''));
グループマッチによる参照を利用した置換
グループ化でのマッチ箇所を、置換文字列からも参照するサンプル。
見慣れた$1や$2などで参照できるということ。
これはよく使うやつ。
var csv = '1,山田,20191012,タロウ\n' + '2,スズキ,20170931,次郎\n' + '3,花田,20140102,五郎\n';
console.log(csv.replace(/^(\d),(.*?),(\d+),(.*?)$/gm, '$1, $3, $2, $4'));
var html = '<body>' + '<h1>heading1</h1>' + '<h2>heading2</h2>' + '<h3>heading3</h3>' + '<h4>heading4</h4>' + '</body>';
console.log(html.replace(/<(h[1-4])>(.*?)<\/\1>/gm, '$1 : $2 \n'));
特定のパターンを含まない行の検索
否定先読み(?!xxx)を使う。
例えば、ログの特定の文字列を抜き出すようなこと。
★を含む行を検索する
var log = '[2018-02-34 12:33:44] execute start \n' +
'[2018-02-34 12:33:44] loop start \n' +
'[2018-02-34 12:33:44] ★ x \n' +
'[2018-02-34 12:33:44] loop start \n' +
'[2018-02-34 12:33:44] ★ x \n' +
'[2018-02-34 12:33:44] loop end \n';
console.log(log.replace(/^(?!.*★).*$/gm, ''))
error, warnを含む行を検索する。
var log = '[2018-02-34 12:33:44] execute start \n' +
'[2018-02-34 12:33:44][error] hogehoge \n' +
'[2018-02-34 12:33:44][info] hogehoge \n' +
'[2018-02-34 12:33:44][user] hogehoge \n' +
'[2018-02-34 12:33:44][warn] hogehoge \n' +
'[2018-02-34 12:33:44][info] hogehoge \n' +
'[2018-02-34 12:33:44][success] hogehoge \n' +
'[2018-02-34 12:33:44][info] hogehoge \n' +
'[2018-02-34 12:33:44][critical] hogehoge \n';
console.log(log.replace(/^(?!.*(error|warn)).*$/gm, ''))