ロジギアジャパン ソフトウェア開発サービス...1 ダナン エンジニア数: 20 ハノイ エンジニア数:68 ホーチミン エンジニア数: 24 ロジギアジャパン
非(エンジニア|プログラマ)でも知っておきたい正規表現【第5回...
-
Upload
hiroyuki-ishikawa -
Category
Engineering
-
view
343 -
download
2
Transcript of 非(エンジニア|プログラマ)でも知っておきたい正規表現【第5回...
株式会社ステラリンク
〒743-0065 山口県光市上島田7-1-1 http://www.stellalink.co.jp/ [email protected]
非(エンジニア|プログラマ)でも知っておきたい正規表現
代表取締役 石川 博之
第5回 WordBench山口(2017/2/18)
自己紹介
石川 博之 Hiroyuki Ishikawa
Twitter: @stellalink_jp @y3sei Facebook: 石川博之(y3sei)
株式会社ステラリンク 代表取締役 有限会社メック システムエンジニア 認定NPO法人 シニアネット光 監事 ←New 光市成人のつどい企画運営委員会 委員長 光市青少年ボランティア育成協議会 企画実行副委員長 光市観光協会 広報委員 山口県指定無形民俗文化財 島田人形浄瑠璃芝居 保存会 会員(人形遣い) ←New(記入漏れ)
元周南コンピュータ・カレッジ 非常勤講師 元山口県ソフトウェアセンター 認定講師 (一財)リスクマネジメント協会 会員
2
http://www.stellalink.co.jp/
WordPressプラグインの カスタマイズ
独自プラグインの開発支援
オリジナルプラグインの開発
WP-Ranking PRO ほか
各種総合サポート
各種不具合修正
サーバ移設
その他なんでもあり。
3
https://plugmize.jp/
テレビ番組の製作協力
APIを使ってFBやTwitterと連動するシステムの製作
業務用ソフトの開発
企業、専門学校やセミナーの講師
研修用自社オリジナルテキスト執筆
BCPの策定支援
たまに工場内にヘルメットと作業服で 入って通信線とシーケンサのロジック修正 など
フルスタックエンジニア、という人種。
7
http://mouvement-neo.jp/
どんな場面で活用できる?
13
「文字列」すべて ※ただし正規表現の機能が提供されている場合に限る
文字列の分割条件
メールアドレスチェック
パターンと一致するデータ中の一部を抽出
プログラム中のパターン検索
HTMLなどのパターン置換
URLのチェック 入力内容のチェック
電話番号チェック 郵便番号チェック
SRE
基本正規表現(BRE)
拡張正規表現(ERE)
AWKサブセット
GNU拡張正規表現
Perl拡張正規表現
JavaScript拡張正規表現
Perl
Python
Ruby
PHP(ereg)
PHP(preg)
Java
JavaScript
C++
C#
統合開発環境
どれで使える?
grep
egrep
sed
awk
gawk (3.0以降)
Tcl (8.2.3以降)
GNU Emacs
PCRE
.NET Framework
テキストエディタ
15
etc...
使える種類は?
etc...
(メタ文字セット)
正規表現メタ文字セットは実質「2+2」種類
17
BRE (基本正規表現)
ERE (拡張正規表現)
PCRE
ed
ex
grep(-E指定なし)
more
sed
vi
egrep
grep(-E指定あり)
Tcl
Emacs
Perl
PHP
Ruby
PHP
※PHPは3種類対応していたが、POSIX正規表現(ereg関数)はPHP5.3.0で非推奨、PHP7.0.0で削除されている
拡張
拡張
etc... etc...
etc...
AWK
awk
etc...
種類の指定 繰り返し条件の指定
20
種類 指定方法
任意の文字全て .
指定した文字 そのまま記述
指定した数字 そのまま記述
指定した記号 そのまま記述
いずれかの1文字 [ 指定したい文字 ]
いずれの文字でもない1字 [^ 対象の文字]
AからZまでの文字 [A-Z]
パターン (パターン)
パターンに一致しない (?!パターン)
n番目のパターン ¥n
種類 指定方法
0回または1回 ?
0回以上 *
1回以上 +
n回~m回 {n,m}
n回以上 {n,}
n回 {n}
※英大小文字は区別して取り扱われます
※基本的に指定に使われている記号は半角(1バイト文字)です
※正規表現のパターンで使う記号と同じ記号を対象の文字として 使用したい場合は、エスケープ処理(該当の1文字の前に「¥」 やバックスラッシュを指定する)を行う
eg.
最小一致させたい場合は後ろにそれぞれ「?」を指定(eg. *? +? ?? {n}?)
A、B、C、D、E、aのいずれか1文字
半角英数(のいずれか1文字)のみのパターン
Googleの「o」が1回以上のパターン
[ABCDEa]
[0-9A-Za-z]+
go+gle または go{1,}gle
★
★
★印はEREなどでの拡張指定
種類をまとめて指定する省略記法(一部抜粋)
21
種類 指定方法 指定方法2 備考
英大小文字 [:alpha:] alphabet
英小文字 [:lower:]
英大文字 [:upper:]
数字 [:digit:] ¥d
数字以外 ¥D
英数全て [:alnum:] alphabet+numeric
英数全て、アンダースコア [:word:] ¥w 単語構成要素
英数全てとアンダースコア以外 ¥W
スペース、タブ、改ページ [:space:]
スペース、タブ [:blank:] ¥s
スペース、タブ以外 ¥S
制御文字 [:cntrl:] control
制御文字以外の全ての文字 [:print:] 可視文字の意
制御文字、スペース、タブ以外 [:graph:]
句読点 [:punct:] punctuation
16進数文字 [:xdigit:] ¥h
★印はEREなどでの拡張指定
★
行の位置 or
22
種類 指定方法
行頭 ^
行末 $
種類 指定方法
いずれか1種類 (パターン指定のとき)
|
eg.
「abc」から始まりその後0文字以上の任意の文字で構成される文字列
「abc」から始まりその後1文字以上の任意の文字で構成される文字列
数字以外の任意の文字から始まる文字列
「abc」以外からはじまる文字列
「WordPress」「Wordpress」「WP」のいずれかの文字列
※行頭や行末以外で使用した場合は 通常の記号または指定記号として解釈する
eg. abcまたはdef ⇒ (abc|def)
^abc.*$
^abc.+$
^[^0-9].*$
^(?!abc).+$
(Word[Pp]ress|WP)
★
★印はEREなどでの拡張指定
英数文字の場合
2017/02/18
2017/2/18
17/2/18
2017年2月18日
平成29年2月18日
23
¥d{2,4}/¥d{1,2}/¥d{1,2}
((明治|大正|昭和|平成)¥d{1,2}|¥d{2,4})年¥d{1,2}月¥d{1,2}日
メールアドレスの場合
24
(RFC5322より一部抜粋) http://www.ietf.org/rfc/rfc5322.txt
【メールアドレスの仕様】
半角の英数字記号であれば使用できない文字はない ただし一部の記号(( ) , . : ; < > @ [ ] " ¥)を含める場合には @ よりも前の部分全体を " で
囲む必要があり、特に " と¥ を含める場合には、直前に¥ を配置しなければならない。 @ の直前には英数字・記号(! # $ % & ' * + - / = ? ^ _ ` { | } ~ ")が使える
ただし " を使う場合には、先頭にも " を配置する必要がある。 @ の前の部分全体を " で囲んでいない場合は . を連続させてはいけない メールアドレスの最初の文字は英数字・記号(! # $ % & ' * + - / = ? ^ _ ` { | } ~ ")が使える
ただし " を使う場合には @ の直前にも " を配置する必要がある。
^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:¥.[a-zA-Z0-9-]+)*$
URIの場合
25
http://www.ietf.org/rfc/rfc3986.txt
RFC3986に定義があるけど忠実にやると壮大なことになるのでざっくりとまとめます!
^https?:¥/¥/(?:[a-zA-Z0-9_¥-¥/¥.,:;~?@=+$%#!]|&)+$
eg.
URIの場合
26
ちなみに…本気でやるとこんな感じになるので見なかったことにしてね。
https?:(//(([-.0-9_a-z~]|%[0-9a-f][0-9a-f]|[!$&-,:;=])*@)?(¥[(([0-9a-f]{1,4}:){6}([0-9a-f]{1,4}:[0-9a-f]{1,4}|(¥d|[1-9]¥d|1¥d{2}|2[0-4]¥d|25[0-5])¥.(¥d|[1-9]¥d|1¥d{2}|2[0-4]¥d|25[0-5])¥.(¥d|[1-9]¥d|1¥d{2}|2[0-4]¥d|25[0-5])¥.(¥d|[1-9]¥d|1¥d{2}|2[0-4]¥d|25[0-5]))|::([0-9a-f]{1,4}:){5}([0-9a-f]{1,4}:[0-9a-f]{1,4}|(¥d|[1-9]¥d|1¥d{2}|2[0-4]¥d|25[0-5])¥.(¥d|[1-9]¥d|1¥d{2}|2[0-4]¥d|25[0-5])¥.(¥d|[1-9]¥d|1¥d{2}|2[0-4]¥d|25[0-5])¥.(¥d|[1-9]¥d|1¥d{2}|2[0-4]¥d|25[0-5]))|([0-9a-f]{1,4})?::([0-9a-f]{1,4}:){4}([0-9a-f]{1,4}:[0-9a-f]{1,4}|(¥d|[1-9]¥d|1¥d{2}|2[0-4]¥d|25[0-5])¥.(¥d|[1-9]¥d|1¥d{2}|2[0-4]¥d|25[0-5])¥.(¥d|[1-9]¥d|1¥d{2}|2[0-4]¥d|25[0-5])¥.(¥d|[1-9]¥d|1¥d{2}|2[0-4]¥d|25[0-5]))|(([0-9a-f]{1,4}:)?[0-9a-f]{1,4})?::([0-9a-f]{1,4}:){3}([0-9a-f]{1,4}:[0-9a-f]{1,4}|(¥d|[1-9]¥d|1¥d{2}|2[0-4]¥d|25[0-5])¥.(¥d|[1-9]¥d|1¥d{2}|2[0-4]¥d|25[0-5])¥.(¥d|[1-9]¥d|1¥d{2}|2[0-4]¥d|25[0-5])¥.(¥d|[1-9]¥d|1¥d{2}|2[0-4]¥d|25[0-5]))|(([0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::([0-9a-f]{1,4}:){2}([0-9a-f]{1,4}:[0-9a-f]{1,4}|(¥d|[1-9]¥d|1¥d{2}|2[0-4]¥d|25[0-5])¥.(¥d|[1-9]¥d|1¥d{2}|2[0-4]¥d|25[0-5])¥.(¥d|[1-9]¥d|1¥d{2}|2[0-4]¥d|25[0-5])¥.(¥d|[1-9]¥d|1¥d{2}|2[0-4]¥d|25[0-5]))|(([0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:([0-9a-f]{1,4}:[0-9a-f]{1,4}|(¥d|[1-9]¥d|1¥d{2}|2[0-4]¥d|25[0-5])¥.(¥d|[1-9]¥d|1¥d{2}|2[0-4]¥d|25[0-5])¥.(¥d|[1-9]¥d|1¥d{2}|2[0-4]¥d|25[0-5])¥.(¥d|[1-9]¥d|1¥d{2}|2[0-4]¥d|25[0-5]))|(([0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::([0-9a-f]{1,4}:[0-9a-f]{1,4}|(¥d|[1-9]¥d|1¥d{2}|2[0-4]¥d|25[0-5])¥.(¥d|[1-9]¥d|1¥d{2}|2[0-4]¥d|25[0-5])¥.(¥d|[1-9]¥d|1¥d{2}|2[0-4]¥d|25[0-5])¥.(¥d|[1-9]¥d|1¥d{2}|2[0-4]¥d|25[0-5]))|(([0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(([0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::|v[0-9a-f]+¥.[!$&-.0-;=_a-z~]+)¥]|(¥d|[1-9]¥d|1¥d{2}|2[0-4]¥d|25[0-5])¥.(¥d|[1-9]¥d|1¥d{2}|2[0-4]¥d|25[0-5])¥.(¥d|[1-9]¥d|1¥d{2}|2[0-4]¥d|25[0-5])¥.(¥d|[1-9]¥d|1¥d{2}|2[0-4]¥d|25[0-5])|([-.0-9_a-z~]|%[0-9a-f][0-9a-f]|[!$&-,;=])*)(:¥d*)?(/([-.0-9_a-z~]|%[0-9a-f][0-9a-f]|[!$&-,:;=@])*)*|/(([-.0-9_a-z~]|%[0-9a-f][0-9a-f]|[!$&-,:;=@])+(/([-.0-9_a-z~]|%[0-9a-f][0-9a-f]|[!$&-,:;=@])*)*)?|([-.0-9_a-z~]|%[0-9a-f][0-9a-f]|[!$&-,:;=@])+(/([-.0-9_a-z~]|%[0-9a-f][0-9a-f]|[!$&-,:;=@])*)*)?(¥?([-.0-9_a-z~]|%[0-9a-f][0-9a-f]|[!$&-,/:;=?@])*)?(#([-.0-9_a-z~]|%[0-9a-f][0-9a-f]|[!$&-,/:;=?@])*)?
日本語文字列の場合
さばんなちほー
じゃんぐるちほー
さばくちほー
へいげんちほー
27
^(さばんな|じゃんぐる|さばく|へいげん)ちほー$
^[ぁ-ん]{1,5}ちほー$
文字コードの関係で「ぁ」(小さい方)
から「ん」までを範囲として指定 (この指定方法は正規表現の“定石”です)
パターンの前後をデリミタで囲う場合の修飾子オプション
28
2つ目のデリミタ(「/」など)の後ろに修飾子を指定可能
修飾子の種類
種類 意味
/i 大文字小文字を区別しない
/m 複数行を扱える、「.」で改行を認識する
/x パターン中の空白やコメントを無視
※言語や実装により別の指定があるものもあります
(主なもの)
eg.
「WordPress」「wOrdpReSs」のいずれもマッチ(大文字小文字を区別しない)
/wordpress/i
文字列置換に応用する場合
29
¥d{2,4}/¥d{1,2}/¥d{1,2}
パターンで指定した括りについてそれぞれ取得できる
(¥d{2,4})/(¥d{1,2})/(¥d{1,2}) 【対象データ】
2017/02/18
グループを追加
¥1 ¥2 ¥3
18 02 2017
【パターン】
¥1年¥2月
2017年02月
長い正規表現パターンのほうが良い正規表現であることが多い
31
web[sv1]: 127.0.0.1 - - [18/Feb/2017:14:00:00 +0900]: "GET / HTTP/1.1" 200
^(.*)¥[(.*)¥]:.*
【対象データ】
↑ここを抜き出したい場合
【回答例】
【正規表現パターン】 【取得結果】
^(¥S+)¥[[^¥]]+]:¥s+¥d{1,3}¥.¥d{1,3}¥.¥d{1,3}¥.¥d{1,3}¥s+¥S+¥s+¥S+¥s+¥[.*
web[sv1]: 127.0.0.1 - -
web
貧欲な「.*」ができるだけ多くマッチさせるため狙いとズレる
取り扱い時の注意事項
言語やライブラリ等の環境ごとに独自拡張がある場合がある
だいたいはトリッキーなことをせずに基本通りやればできるハズ
方言きつい…
どの種類(まず基本か拡張か)の正規表現メタ文字セットを使用しているかが、関数によって異なる言語がある(特にPHP)
preg系かそれ以外か
言語で使用する際に前後を所定の文字で挟む必要がある場合がある
PHPのpreg系ではデリミタでパターンの前後を挟む必要がある
その場合はデリミタの文字はそのままでは使えないのでエスケープをお忘れなく
そもそもきちんとマッチできているかがわかりにくい
関数の戻り値をチェックする
Web上にあるチェックツールで再確認する
チェックツールを自作する 32
参考文献
正規表現
http://www.kt.rim.or.jp/~kbk/gawk-30/gawk_5.html
正規表現 (Perl 互換)
http://php.net/manual/ja/book.pcre.php
PHP: POSIX 正規表現関数
http://php.net/manual/ja/ref.regex.php
perlretut - Perl の正規表現のチュートリアル - perldoc.jp
http://perldoc.jp/docs/perl/5.20.1/perlretut.pod
どのUNIXコマンドでも使える正規表現
http://qiita.com/richmikan@github/items/b6fb641e5b2b9af3522e
正規表現メモ
http://www.kt.rim.or.jp/~kbk/regex/regex.html
【正規表現】文字列の否定、ある文字列を含まない : nymemo
http://nymemo.com/phpcate/293/
正規表現:悪い表現、いい表現、最良の表現 | POSTD
http://postd.cc/regexes-the-bad-the-better-and-the-best/
PHP正規表現チェッカー ver1.0.3
http://www.rider-n.sakura.ne.jp/regexp/regexp.php
37