「正規表現パターン文字列」を関数へ渡して処理する
状態:確認中
閲覧数:2,398
投稿日:2016-02-28
更新日:2018-09-03
他言語との相違点
「Perl」や「JavaScript」
・言語そのものに正規表現が備わっているため直接プログラムに正規表現を書く
PHP
・「正規表現パターン文字列」を関数へ渡して処理する
・文字列なので、パターンの中にPHPで特殊な意味を持つ文字(\${}など)を含む場合は、正規表現として評価される前に文字列として評価されるので注意が必要
・後方参照は"\1" で表現する言語が多いが、PHPでは、 $1 でも取得できる
PHPで使える正規表現
3種類ある
・PCRE(preg_**関数)
・mberegex(mb_ereg_**関数)
・POSIX(ereg_**関数)
PCRE — 正規表現 (Perl 互換)
・PCREはPerl Compatible Regular Expression(Perlと互換性のある正規表現)の略だが、完全に一致しているわけではない
・正規表現は、スラッシュ (/) などのデリミタで囲う必要がある
→ PCRE 正規表現構文
mberegex(mbstring の正規表現)
・mb_ereg_**関数は名前だけereg_**関数から借りているが、中身的には全く別の実装
POSIX Regex — 正規表現 (POSIX 拡張)
・バイナリセーフではないため、POSIX(ereg_**関数)は利用しない
「POSIX正規表現」と「PCRE正規表現」の違い
「POSIX正規表現」と「PCRE正規表現」の違い
1.PCRE 関数では、パターンを デリミタ で囲まなければならない
2.POSIX とは異なり、PCRE 拡張モジュールには大文字小文字を区別しないマッチング専用の関数がない
・同等の機能は、i (PCRE_CASELESS) パターン修飾子 でサポート
3.マッチするパターンが見つかった場合の挙動
・POSIX 関数は、いちばん左側にある最も長くマッチするパターンを探す
・しかし PCRE は、マッチするパターンが最初に見つかった時点で処理を終了
一覧
PCRE関数 | POSIX関数 |
---|---|
preg_replace | ereg_replace |
同上 | eregi_replace |
preg_match | ereg |
同上 | eregi |
preg_split | split |
同上 | spliti |
パターン修飾子(末尾のデリミタの後ろに記述)
正規表現パターンに使用可能な修飾子
デフォルトのPCRE(マルチラインモードではなくシングルラインモード)
・検索対象文字列を(実際には複数行からなる 場合でも)単一の行からなるとして処理する
・「行頭」メタ文字 (^) は、対象文字列の最初にしかマッチしない
・「行末」メタ文字 ($) は、文字列の最後、または (D 修飾子が設定されていない場合) 最後にある改行記号の前のみにしかマッチしない
i
大小文字の違いを無視する
・この修飾子を設定すると、パターンの中の文字は 大文字にも小文字にもマッチする
※PCRE_CASELESS
m
マルチラインモードにする
・^と$が改行の直前直後にマッチ
・この修飾子を設定すると、「行頭」および「行末」メタ文字は 対象文字列において、文字列の最初と最後に加えて、 各改行の直前と直後にそれぞれマッチする
※PCRE_MULTILINE
s
シングルラインモードにする
・「.」が改行にマッチする
シングルラインモードとは?
・改行・インデントといった、整形に関わる記号をすべて「通常の文字」として扱い、「検索される側の文字列」を1行としてみなすモード
u
ユー
・マルチバイト(UTF-8)対応
デリミタ
delimiters で囲む必要がある
PCRE 関数を使用する際には、パターンを delimiters で囲む必要がある
・表現の前後にデリミタが必要
デリミタとして使用可能な文字
・「英数字」「バックスラッシュ」「空白文字」以外の任意の文字
デリミタとしてよく使われる文字
・スラッシュ (/)
・ハッシュ記号 (#)
・チルダ (~)
/foo bar/
#^[^0-9]$#
+php+
%[a-zA-Z0-9_-]%
角括弧形式のデリミタ
角括弧形式のデリミタも使用可能
・「開き角括弧」「閉じ角括弧」がそれぞれ「開始デリミタ」「終了デリミタ」を表す形式となる
角括弧形式のデリミタとして有効な値
・()
・{}
・[]
・<>
(this [is] a (pattern))
{this [is] a (pattern)}
[this [is] a (pattern)]
<this [is] a (pattern)>
パターン内でメタ文字を使うときのエスケープは不要
パターンの中でデリミタ文字をマッチさせたい場合(パターンの中にデリミタ文字自体が含まれる場合)は、バックスラッシュによるエスケープが必要
・他のデリミタと同様、(メタ文字としてではなく) リテラルとして扱う(デリミタ文字をマッチさせたい)場合は、 バックスラッシュでエスケープする必要がある
※パターン内でデリミタが頻繁にあらわれる場合は、 デリミタを別の文字に変更したほうが読みやすくなる
具体例
下記二文は、同じ意味
・デリミタ(ここでは/) をメタ文字としてではなくリテラルとして扱う(デリミタ文字をマッチさせたい)場合は、 バックスラッシュでエスケープする必要がある
/http:\/\//
・デリミタを別の文字(ここでは#)に変更した例#http://#
下記二文は、同じ意味
・デリミタは「#」。/をエスケープする必要がない
preg_match('#^/hoge[0-9]+\.html$#', $_SERVER['REQUEST_URI'] )){
・デリミタは「/」。/エスケープが必要 preg_match('/^\/hoge[0-9]+\.html$/', $_SERVER['REQUEST_URI'] )){
preg_quote() 関数
パターンに使う文字列をエスケープすることができる
・オプションの二番目のパラメータで、エスケープするデリミタを指定する
パターン修飾子
終了デリミタの後に パターン修飾子 を付加することも出来る
大文字小文字を区別しないマッチを行う例
・1つ以上のアルファベット(大文字小文字関係なし)
#[a-z]#i
・デリミタ#
・修飾子i
・デリミタ
メタキャラクタ
メタ文字
- | 内容 | 読み方 | 同義 |
---|---|---|---|
\ | 直後のメタ文字をエスケープする | バックスラッシュ | - |
* | 直前の表現の0回以上の繰り返し。最長一致でマッチ | - | 直前に置かれている正規表現の可能な限り大きい繰り返しに マッチする。繰り返しの回数は0回でも構わない。「0回以上」の「0回」とは「登場しない」ことを指す。つまり、「直前の文字が登場しないか、もしくは1回以上登場」と同義。 例 ・「fo*」は、「fo」にも「foo」にもマッチするし、「f(oが一個もない)」にもマッチする |
? | - | - | - |
| | 選択枝の開始。何れかの文字列 | パイプ | - |
具体例
- | 内容 | 備考 |
---|---|---|
\. | .の特殊な意味を無効にするため、エスケープ | - |
文字を表現するメタキャラクタ
包括的な文字型
- | 内容 | 読み方 | 同義 |
---|---|---|---|
. | 改行以外の任意の1文字 | ドット | - |
\d | 任意の数字1文字 | - | [0-9] |
\D | 数字以外の任意の1文字 | - | [^0-9] |
\s | 空白1文字 | - | [ \r\t\n\f\v] |
\S | 空白以外の任意の1文字 | - | [^ \r\t\n\f\v] |
\w | 任意の「英数字かアンダースコア(_)」1文字 | - | - |
\W | 「英数字かアンダースコア(_)」以外の任意の1文字 | - | - |
繰り返しを表現するメタキャラクタ(量指定子)。quantifier
量指定子
- | 内容 | 同義 |
---|---|---|
+ | アスタリスク ・直前の表現の0回以上の繰り返し ・単一文字の量指定子 |
{0,} |
\t | プラス ・1回以上の繰り返し ・単一文字の量指定子 |
{1,} |
? | 疑問符 ・0回または1回の出現 ・単一文字の量指定子 |
{0,1} |
{n} | 波括弧 ・n回の繰り返し |
- |
{n,} | 波括弧 ・n回以上の繰り返し |
- |
{n,m} | 波括弧 ・n回以上、m回以下の繰り返し |
- |
具体例
- | 内容 | 備考 |
---|---|---|
[0-9]+ | 任意の数字1文字以上 | - |
[^/]+ | /以外の1文字以上 [] の中の ^ は否定の意味 |
- |
量指定子に続けて?を記述すると、最短でのマッチングを実施
位置を表現するメタキャラクタ(アンカー)
文字クラス
文字クラス
- | 内容 | 同義 |
---|---|---|
[] | [ ]内ではメタ文字を通常の文字として扱うのでエスケープする必要はない | - |
[abc] | a,b,cいずれかの1文字 | - |
[^abc] | a,b,c以外の1文字 | - |
[A-Z] | 大文字のアルファベット1文字 | - |
[あ-お] | あ行 | - |
[は-ほば-ぼぱ-ぽ] | は行、ば行、ぱ行 | - |
[0-9] | 任意の数字1文字 | \d |
[^0-9] | 数字以外の任意の1文字 | \D |
[a-zA-Z0-9] | アルファベットか数字1文字 | - |
[!-~] | 半角文字1文字 | - |
[ \r\t\n\f\v] | 空白1文字 | \s |
[^ \r\t\n\f\v] | 空白以外の任意の1文字 | \S |
半角英数字およびアンダースコアを3 ~ 20 文字以内
preg_match('/^\w{3,20}$/', $user_name)
グループ化構成体
サブパターン
- | 内容 | 読み方 | 備考 |
---|---|---|---|
( ) | グループ化。括弧を使うと、グループにできる | 丸括弧 | - |
\1 \2 ... \n | 後方参照。n 番目の括弧(正規 表現 ( ) グルーピング)にマッチした文字列にマッチ | - | - |
(?: ) | 後方参照を伴わないグループ化。つまり、\1, \2 (あるいは、 $1, $2)などの対象にはならず、 単純なグループ化の用途で使用 | - | - |
具体例
1回以上のab、かつ行頭ab、かつ行末ab
print_r(preg_match("#^(ab)+$#i", "ababab")); //1回マッチ。最初にマッチした時点でpreg_match()は検索を止めるため
print_r(preg_match("#^(ab)+$#i", "ababa")); //0マッチ
後方参照
後方参照とは?
・正規表現中のある位置にマッチした文字列を、後から使い回すこと
・後方参照を行うには、後から参照したい部分パターンを予めグループ化しておく
・すると、グループ化した(括弧で括った)正規表現にマッチした部分文字列は、正規表現内でキャッシュされる
・使う時にそのグループの出現位置を指定することでそこにマッチした文字列を参照
・つまり、括弧で括ったグループは、後で使いまわせる
・具体的には、\g1とか\g2とかに割り当てられていて、正規表現中で利用可能
※gには特別な意味がある。省略は可能だが、 違うアルファベットでは意味を成さない
\g1、\g2は、O.K.
\k1、\k2は、NG
非格納グループ(非キャプチャグループ)
非格納グループとは?
・通常、グループ化すると後方参照用にキャッシュされるが、 「(?:)」を利用すると、割り当てから外れ、キャッシュされなくなる(その結果、参照されなくなる)こと
・グループはないものとして扱われる
・正規表現