正規表現

テキスト処理正規表現

「正規表現パターン文字列」を関数へ渡して処理する

 状態:確認中  閲覧数:2,251  投稿日: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正規表現」の違い

 閲覧数:580 投稿日:2018-01-13 更新日:2018-02-01 

「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


パターン修飾子(末尾のデリミタの後ろに記述)

 閲覧数:520 投稿日:2018-01-21 更新日:2018-09-07 

正規表現パターンに使用可能な修飾子


デフォルトのPCRE(マルチラインモードではなくシングルラインモード)
・検索対象文字列を(実際には複数行からなる 場合でも)単一の行からなるとして処理する
・「行頭」メタ文字 (^) は、対象文字列の最初にしかマッチしない
・「行末」メタ文字 ($) は、文字列の最後、または (D 修飾子が設定されていない場合) 最後にある改行記号の前のみにしかマッチしない

i


大小文字の違いを無視する
・この修飾子を設定すると、パターンの中の文字は 大文字にも小文字にもマッチする
※PCRE_CASELESS

m


マルチラインモードにする
・^と$が改行の直前直後にマッチ
・この修飾子を設定すると、「行頭」および「行末」メタ文字は 対象文字列において、文字列の最初と最後に加えて、 各改行の直前と直後にそれぞれマッチする
※PCRE_MULTILINE

s


シングルラインモードにする
・「.」が改行にマッチする

シングルラインモードとは?
・改行・インデントといった、整形に関わる記号をすべて「通常の文字」として扱い、「検索される側の文字列」を1行としてみなすモード

u


ユー
・マルチバイト(UTF-8)対応




デリミタ

 閲覧数:483 投稿日:2018-01-21 更新日:2018-07-27 

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



デリミタ

メタキャラクタ

 閲覧数:510 投稿日:2018-01-21 更新日:2018-07-31 

メタ文字

- 内容 読み方 同義
\ 直後のメタ文字をエスケープする バックスラッシュ -
* 直前の表現の0回以上の繰り返し。最長一致でマッチ - 直前に置かれている正規表現の可能な限り大きい繰り返しに マッチする。繰り返しの回数は0回でも構わない。「0回以上」の「0回」とは「登場しない」ことを指す。つまり、「直前の文字が登場しないか、もしくは1回以上登場」と同義。

・「fo*」は、「fo」にも「foo」にもマッチするし、「f(oが一個もない)」にもマッチする
? - - -
| 選択枝の開始。何れかの文字列 パイプ -

具体例



- 内容 備考
\. .の特殊な意味を無効にするため、エスケープ -


文字を表現するメタキャラクタ

 閲覧数:477 投稿日:2018-01-21 更新日:2018-07-26 

包括的な文字型


- 内容 読み方 同義
. 改行以外の任意の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文字 - -


制御文字を表現するメタキャラクタ

 閲覧数:482 投稿日:2018-01-21 更新日:2018-07-25 

非表示文字〔制御コードなど〕


- 内容 備考
\n 改行 -
\t タブ -


繰り返しを表現するメタキャラクタ(量指定子)。quantifier

 閲覧数:614 投稿日:2018-01-21 更新日:2018-07-26 

量指定子

- 内容 同義
+ アスタリスク
・直前の表現の0回以上の繰り返し
・単一文字の量指定子
{0,}
\t プラス
・1回以上の繰り返し
・単一文字の量指定子
{1,}
? 疑問符
・0回または1回の出現
・単一文字の量指定子
{0,1}
{n} 波括弧
・n回の繰り返し
-
{n,} 波括弧
・n回以上の繰り返し
-
{n,m} 波括弧
・n回以上、m回以下の繰り返し
-

具体例


- 内容 備考
[0-9]+ 任意の数字1文字以上 -
[^/]+ /以外の1文字以上
[] の中の ^ は否定の意味
-

量指定子に続けて?を記述すると、最短でのマッチングを実施

位置を表現するメタキャラクタ(アンカー)

 閲覧数:627 投稿日:2018-02-20 更新日:2018-07-26 

アンカー 



- 内容 読み方 備考
^ 行頭 キャレット -
$ 行末 ドル記号 -


文字クラス

 閲覧数:481 投稿日:2018-02-27 更新日:2018-07-27 

文字クラス


- 内容 同義
[] [ ]内ではメタ文字を通常の文字として扱うのでエスケープする必要はない -
[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)






グループ化構成体

 閲覧数:495 投稿日:2018-07-26 更新日:2018-09-07 

サブパターン


- 内容 読み方 備考
( ) グループ化。括弧を使うと、グループにできる 丸括弧 -
\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

非格納グループ(非キャプチャグループ)


非格納グループとは?
・通常、グループ化すると後方参照用にキャッシュされるが、 「(?:)」を利用すると、割り当てから外れ、キャッシュされなくなる(その結果、参照されなくなる)こと
・グループはないものとして扱われる


正規表現


preg_match

コメント投稿(ログインが必要)



週間人気ページランキング / 6-7 → 6-13
順位 ページタイトル抜粋 アクセス数
1 PHPで定数を定義する方法は2種類ある / 配列定数の定義 9
2 コード例 … 「例外処理」はネストすることができる 5
2 ブラウザを閉じたらセッションデータはどうなるの? | セッション 5
3 Parse error: syntax error, unexpected 'public' (T_PUBLIC) | Parse error(エラーメッセージ) 4
4 ガベージコレクション | 機能 3
4 Warning: Unexpected character in input: '\' (ASCII=92) state=1 in ○○.php on line △△ | Warning(エラーメッセージ) 3
4 curl で Cookie を使用する 3
4 PHPにおけるメソッドのオーバーライドについて /「引数の数や型は、親クラスのメソッドと完全に一致していなければなりません。」とは具体的にどういう意味ですか? 3
4 Catchable fatal error: Object of class DateTime could not be converted to string | Fatal error(エラーメッセージ) 3
4 Fatal error: Uncaught PDOException: SQLSTATE[HY000] [2002] Connection refused | Fatal error(エラーメッセージ) 3
4 Warning: include() [function.include]: Failed opening '**.php' for inclusion (in | Warning(エラーメッセージ) 3
4 ( ! ) Deprecated: implode(): Passing glue string after array is deprecated. Swap the parameters in ★★★ headless-chromium-php/vendor/wrench/wrench/lib/Wrench/Protocol/Protocol.php | エラーメッセージ 3
5 Fatal error: Wrong parameters for Exception([string $exception [, long $code ]]) | Fatal error(エラーメッセージ) 2
5 セッション管理が必要な理由は、HTTPプロトコルには状態を保持する機能がないため | セッション 2
5 Fatal error: require_once(): Failed opening required 'PEAR.php' | Fatal error(エラーメッセージ) 2
5 Fatal error: Uncaught RuntimeException: SplFileObject::__construct(): failed to open stream: Permission denied in | Fatal error(エラーメッセージ) 2
5 ( ! ) Fatal error: Uncaught PDOException: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'カラム名' cannot be null | Fatal error(エラーメッセージ) 2
5 session_start() | セッション 2
5 @ | 演算子 2
5 Parse error: syntax error, unexpected T_REQUIRE_ONCE, expecting T_FUNCTION | Parse error(エラーメッセージ) 2
2024/6/14 1:01 更新