PHPでの正規表現

作成日:2017-12-06, 更新日:2021-10-26

諸々

パターン修飾子

i 大文字と小文字の違いを無視する
s 改行文字を無視し、1行とみなして調べる
u 対象文字列をUTF-8として扱う
e 置換文字列をPHPコードとして実行

行頭、行末

^ 後に続く文字を先頭とみなす( 「^a」で「aで始まる行」 )
$ 前にある文字を末尾とみなす( 「a$」で「aで終わる行」 )

制御

? 最小一致

繰り返し

* 前の文字を0個以上繰り返し( a* )
+ 前の文字を1個以上繰り返し( a+ )
? 前の文字が0個、もしくは1個( a? )
*? 前の文字が0個以上かつ最小回数マッチ
+? 前の文字が1個以上かつ最小回数マッチ
?? 前の文字が0個、もしくは1個以上かつ最小回数マッチ
{x,y} 前の文字をx個~y個続き( a{1,3} )
{x} 前の文字がx個続き( a{3} )
{x,} 前の文字がx個以上続き( a{3,} )

任意の文字

. 改行を除く任意の1文字( . )
(hoge) 文字列単位で判別

グループ

[abc] 括弧内の文字のいずれか1文字
[a-z] 括弧内の範囲指定
[^a-z] 括弧内の範囲指定を否定

キャプチャ

() 括弧内のパターンを1キャプチャとみなし、配列戻り値の要素1以降に格納されたりする

パターンの略記法

\d [0-9] 数字
\D [^0-9] 数字以外
\w [a-zA-Z0-9] 単語の一部とみなされる文字
\W [^a-zA-Z0-9] 単語の一部ではない文字
\s [\f\n\r\t\v] 空白文字
\S [^ \f\n\r\t\v] 空白文字以外

メタ文字

\a アラート
\b バックスペース
\e エスケープ
\f 改ページ
\n 改行
\r 復帰
\t 水平タブ(通常タブ)
\v 垂直タブ
\0?? 制御コード 8進数
\x?? 制御コード 16進数

文字クラス「[ ]」で、「\」をつける必要のある記号

基本、下の4つ。

- マイナスハイフン
^ 山形記号
] 閉じ角かっこ
\ バックスラッシュ

サンプル

日本語を使うなら「/〇〇〇/」ではなく「/〇〇〇/u」にするのが無難。

半角英数のみ
/^[a-zA-Z0-9]+$/
全角英数のみ
/^[a-zA-Z0-9]+$/
半角数字のみ
/^[0-9]+$/
数字(半角・全角)のみ
/^[0-90-9]+$/
ひらがな、カタカナ、漢字のみ
/^[ぁ-んァ-ヶー一-龠]+$/
ひらがな、カタカナ、漢字、「、」と「。」のみ
/^[ぁ-んァ-ヶー一-龠、。]+$/
ひらがな、カタカナ、漢字、半角英数、全角数字のみ
/^[ぁ-んァ-ヶーa-zA-Z0-9一-龠0-9]+$/
半角・全角の連続した空白
/( | )+/
メールアドレス(簡易版)
/^([a-zA-Z0-9])+([a-zA-Z0-9\._-])*@([a-zA-Z0-9_-])+([a-zA-Z0-9\._-]+)+$/

※すべてのメアドは網羅されないので注意

半角記号
/^[ -\/:-@\[-`\{-\~]+$/
1バイト文字ではない文字
/[^\x01-\x7E]/
改行を含む任意の1文字 / 「.*」「.+」等だと改行が含まれない
/[\s\S]+/

タグ関連

タグ指定無しでHTMLタグ
開始タグと中身と閉じタグ付き。imgタグは取得できない
/(<([\w]+)[^>]*>)(.*)(<\/\\2>)/ui
タグ指定アリでHTMLタグ: 改行は含めない
開始タグと中身と閉じタグ付き。imgタグは取得できない
/(<div[^>]*?>.*?<\/div>)/ui
タグ指定アリでHTMLタグ: 改行コード含む
開始タグと中身と閉じタグ付き。imgタグは取得できない
/(<div[^>]*?>[\s\S]*?<\/div>)/ui
タグ指定無しで開始タグのみ(imgタグやbrタグも含む)
/<([\w]+)[^>]*>/ui
指定した属性のみ
※「=」の前後に空白が入る可能性を考慮
/(href|src) *?= *?("|'."'".')(.+?)(\\2)/ui
指定した属性の値が「http」ではじまるもの
※「=」の前後に空白が入る可能性を考慮
/(href|src) *?= *?("|'."'".')(http[s]*:\/\/?.+?)(\\2)/ui
指定した属性の値が指定したURLではじまるもの
※「=」の前後に空白が入る可能性を考慮
/(href|src) *?= *?("|'."'".')(http:\/\/hogehoge\.com.+?)(\\2)/ui
指定した属性を含むタグ
/<([\w]+)[^>]*((href|src) *?= *?("|')(http[s]*:\/\/?.+?)(\4))[^>]*>/ui

▼ちょっぴり中身を見やすくしたもの

$sub = '(href|src) *?= *?("|'."'".')(http[s]*:\/\/?.+?)(\\4)';
$attr_withTag = '/<([\w]+)[^>]*(' . $sub . ')[^>]*>/ui';

その他サンプル

▼CSVの項目の置き換え(preg_replace())

$csv = 'ささみ,ささみわさび,砂肝,ナンコツ';
$old = '砂肝';
$new = 'モチベーコン';

// ▼【行頭 or 「,」】【$old】【「,」or 行末】の組合せ
$regexp = '(^|,)(' . $old . ')(,|$)'; // 「()」で区切られたヤツが「$1~$3」
echo preg_replace('/'.$regexp.'/u', "$1".$new."$3", $csv); // $1と$3はそのまま表示。

「$old」が1単語なら「$csv」をばらして配列にしてループで回しても良い
※正規表現と配列をループ・・・どっちが早いかは未調査。

「$old」も「CSV」ってときがあったので「preg_replace()」を使ってみた。

注意

改行コードを含む任意の文字

「任意の文字」ってコトで「.」としたいがこの場合「改行コードや空白類を含まない任意の文字」となる。

だから、改行コードを含めたい場合は「\s\S」とする必要がある。