0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

プログラミングPHP 弟4章 4.8 正規表現

Last updated at Posted at 2017-12-13

PHPの正規表現モジュール

正規表現の種類 POSIX mbstring Perl互換
正規表現の構文 POSIX Rubyなど Perl
拡張モジュール regex mbstring PCRE
関数名の接頭語 ereg_ mb_ preg_
備考 PHP5.3.0で非推奨 鬼車ライブラリ PCREライブラリ

正規表現の基本

/pattern/

正規表現パターン「.」

.は任意の1文字だが、改行を含む、含まないの扱いが以下で異なる。

mbstringの正規表現パターン「.」

/m オプションあり(デフォルト):改行を含む任意の1文字
/m オプションなし: 改行を除く任意の1文字

Perl互換の正規表現パターン「.」

/s オプションあり: 改行を含む任意の1文字
/s オプションなし(デフォルト) : 改行を除く任意の1文字

#文字クラス []
[]で囲む [^pattern] は、文字クラスの否定
ex)

preg_match("/c[aeiou]t/","I cut my hand") //1を返す
preg_match("/c[^aeiou]t/","I cut my hand") //0を返す

選択肢 |

ex)

preg_match("/cat|dog/", "the cat") //1を返す
preg_match("/cat|dog/", "the dog") //1を返す
preg_match("/cat|dog/", "the rabbit") //0を返す

繰り返し ?, * , +, {

量指定子 意味
? 0 or 1回
* 0回以上
+ 1回以上
{n n回
{n, m} n回以上m回以下
{n,} n回以上

★通常は、できるだけ長い範囲にマッチするようにするが、できるだけ短い範囲にマッチさせたい場合は、両指定子の後ろに?をつける
ex)

貪欲な量指定子 貪欲でない量指定子  意味
? ?? 0 or 1回
* *? 0回以上
+ +? 1回以上
{n {n? n回
{n, m} {n, m}? n回以上m回以下
{n,} {n,}? n回以上

選択肢 |

ex)

preg_match("/^(cat|dog)$/", "cat") //1を返す

デリミタ

/以外にも、英数字とバックスラッシュ以外の文字ならなんでもデリミタとして使える
ex)

preg_match("/\/usr\/local\//", "/usr/local/bin/perl"); //1を返す

preg_match("#/usr/local/#", "/usr/local/bin/perl"); //1を返す

文字クラス

クラス 説明
[:alnum:] 英数字
[:alpha:] アルファベット
[:ascii:] 7ビットのASCII文字
[:brank:] スペース、タブ
[:cntrl:] 制御文字
[:digit:] 数字
[:graph:] 可視文字
[:upper:] 英大文字
[:lower:] 英小文字
[:print:] 印字可能な文字 graph + 空白とタブ
[:punct:] ピリオド、セミコロンなどの記号
[:space:] 空白(改行、キャリッジリターン、タブ、スペース、垂直タブ
[:xdigit:] 16進数字
\s 空白文字
\S 空白文字以外
\w ワード(識別子)文字
\W ワード(識別子)文字以外
\d 数字
\D 数字以外

アンカー

アンカー マッチする対象
^ 文字列の先頭、行頭 (/mフラグが有効な場合は、\nの直後)
$ 文字列の末尾、行末 (/mフラグが有効な場合は、\nの直前)
[[:<:]] 単語の先頭
[[:>:]] 単語の末尾
\b ワードの境界
\B ワードの境界以外
\A 文字列の先頭
\Z 文字列の末尾、あるいは最後の\nの直前
\z 文字列の末尾

キャプチャしないグループ(?:subpattern)

(?:subpattern) とするとキャプチャしない
ex)

preg_match("/(?:ello)(.*)/", "jello biafra", $match);

→$match[1]はelloは入らず、biafraが入る。

Perl互換正規表現 後置オプション(フラグ)

修飾子 意味
/regexp/i 大文字、小文字を区別しないマッチを行う
/regexp/s ピリオド(.)を、改行(\n)も含めた任意の文字にマッチさせる
/regexp/x パターンから空白文字やコメントを除去する
/regexp/m 複数行モード。キャレット(^)は、改行(\n)の直後の文字、ドル記号($)は、改行(\n)の直前の文字にマッチさせる
/regexp/e 置換文字にPHPのコードを指定すると、そのコードをeval()した結果で文字列を置き換える
/regexp/U サブパターンの貪欲さの指定を反転させる
/regexp/u パターン文字列をUTF-8として扱う
/regexp/X バックスラッシュの後に特別な意味を持たない文字が続いている場合にエラーを発生させる
/regexp/A パターンの最初の文字が^であるかのように、先頭の文字にアンカーを設定する
/regexp/D $を行末にのみマッチさせるようにする
/regexp/S パターンの構造をより慎重に解析し、ループ内などでの次回以降の実行速度を少し高速にする。

mbstring 正規表現 後置オプション

修飾子 意味
/regexp/m ピリオド(.)を、改行(\n)も含めた任意の文字にマッチさせる
/regexp/s 複数行モードでない。(mgstring正規表現は、デフォルトが複数行モード = Perl互換で/mオプションを指定している状態)

インラインオプション (?flags:subpattern)または(?flags)

パターンの一部にだけ適用するオプション(フラグ)の指定
ex)

preg_match('/I like (?i:PHP)/' , 'I like pHp'); //1を返す

マイナス文字の後にオプション文字を指定すると、オプションを無効にできる
ex)

preg_match('/a(?i)b(?-i)c/' , 'aBc'); //1を返す
preg_match('/a(?i)b(?-i)c/' , 'aBC'); //0を返す

先読みと戻り読み

書式 意味
(?=subpattern) 肯定先読み
(?!subpattern) 否定先読み
(?<=subpattern) 肯定戻り読み
(?<!subpattern) 否定戻り読み

ex)

  • foo(?=bar) 直後にbarがあるfoo(barは含まない)
  • foo(?!bar)直後にbarがないfoo(barは含まない)
  • (?<=bar)foo 直前に barがあるfoo(barは含まない)
  • (?<!bar)foo 直前にbarがないfoo(barは含まない)

条件式

(?(条件)yespattern|nopattern)

関数 (mbstring)

mb_regex_set_options([string $options])

mgstring正規表現の関数が使用するオプションや構文モードを取得または設定する。
$optionsに設定可能なオプション、構文モードは以下

mb_regex_set_options()のオプション

オプション文字 意味
i 大文字小文字の区別なし
x 拡張パターン形式を使用 (空白、#以降を無視)
m 「.」が改行にマッチ
s ^は\A(文字列の先頭), $は\Z(文字列の末尾)と同一 ,NOT複数行モード
p mとsを両方指定と同一
l 貪欲なマッチ(最も長くマッチするものを探す)
n 空のマッチを無視
e 結果のコードをeval()する

mb_regex_set_options()の構文モード

モード 意味
j java
u GNU regex
g grep
c Emacs
r Ruby
z Perl
b POSIX Basix regex
d POSIX Extended regex

★デフォルトのオプションは「msr」

mb_regex_encoding([string $encoding])

mbstring正規表現関数が使用する文字エンコーディングを取得または設定する

mb_ereg_match(string $pattern, string $string [, string $option = "msr"])

マッチすればtrue,そうでない場合はfalseを返す

mb_ereg(string $pattern, string $string [, array $regs])

$regsはマッチ結果。$regs[0]にはマッチした文字列全体、$regs[1]以降には、サブパターンにマッチした要素が入る。
戻り値はマッチすれば1、そうでなければ0を返す。

mb_eregi

mb_ereg の、大文字小文字の区別を行わない関数

mb_ereg_search_init(), mb_ereg_search(),mb_ereg_search_getregs()

  • mb_ereg_search_init(string $string [,string $pattern[, string $option = "msr"]])
    マッチング処理の初期化

  • mb_ereg_search([string $pattern [,string $option = "ms"]])
    マッチングの実行

  • mb_ereg_search_getargs()
    マッチング部分の取り出し
    戻り値 = array
    最初の要素はパターンにマッチした文字列全体、
    2番目以降の要素はサブパターンにマッチした部分

ex)

$pattern = '<h([0-9])>';
$subject = '<h1><h2><h3>';
mb_ereg_search_init($subject, $pattern);
while(mb_ereg_search()){
	$regs = mb_ereg_search_getregs();
	print_r($regs);
}

結果

Array
(
    [0] => <h1>
    [1] => 1
)
Array
(
    [0] => <h2>
    [1] => 2
)
Array
(
    [0] => <h3>
    [1] => 3
)

mb_ereg_replace(string $pattern, string $replacement, string $string [, string $option = "msr" )

文字列をパターンで検索し、マッチした部分を置換文字列に置換した結果の文字列を変えず。マッチしない場合は元の文字列をそのまま返す。
第2引数に与える置換文字列では、パターン全体に一致した部分を\0,サブパターンに一致した部分を\1,\2…で参照することができる。
ex)

$pattern = '([0-9]+)/([0-9]+)/([0-9]+)';
$replacement = '\1年 \2月 \3日';
$string = '今日は2013/12/31です';
echo mb_ereg_replace($pattern, $replacement, $string);

結果: 今日は2013年 12月 31日です

mb_eregi_replace()

mb_ereg_replaceとの違いは、大文字小文字の区別を行わない事のみ

mb_split(string $pattern, string $string [,int $limit = -1])

文字列を、パターンで区切り、結果を配列で返す。$limitは最大の区切り個数

関数 (Perl互換)

preg_match(string $pattern, string $string [,array $captured ])

stringにpatternがマッチする場合は1を、そうでない場合は0を返す。captured[0]にはマッチした文字列全体が、captured[1]にはサブパターンに一致した部分が入る。
★preg_matchi()関数は存在しないので、パターンの中でiフラグを使用する。

preg_match_all(string $pattern, string $string, array $matches, [, order])

最後にマッチした場所以降でマッチを繰り返し、マッチが行えなくなるまで処理を続ける。
orderにはPREG_PATTERN_ORDER(デフォルト)か、PREG_SET_ORDERのいずれかを指定する。
ex)

  • PREG_PATTERN_ORDER
    $matches[0] はパターン全体にマッチした文字列の配列、 $matches[1] は第 1 のキャプチャ用サブパターンにマッチした文字列の配列、 といった順番となる。
preg_match_all("|<[^>]+>(.*)</[^>]+>|U",
    "<b>example: </b><div align=left>this is a test</div>",
    $out, PREG_PATTERN_ORDER);
echo $out[0][0] . ", " . $out[0][1] . "\n";
echo $out[1][0] . ", " . $out[1][1] . "\n";

結果:

<b>example: </b>, <div align=left>this is a test</div>
example: , this is a test
  • PREG_SET_ORDER

$matches[0] は 1 回目のマッチングでキャプチャした値の配列、 $matches[1] は 2 回目のマッチングでキャプチャした値の配列、 といった順序となる。

preg_match_all("|<[^>]+>(.*)</[^>]+>|U",
    "<b>example: </b><div align=left>this is a test</div>",
    $out, PREG_SET_ORDER);
echo $out[0][0] . ", " . $out[0][1] . "\n";
echo $out[1][0] . ", " . $out[1][1] . "\n";

結果:

<b>example: </b>, example:
<div align="left">this is a test</div>, this is a test

preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )

$subject が置換元。string または array。戻り値の型は$subjectの型と同一。 $limitは、置換する最大数。デフォルト= -1 (全て置換)

array preg_split ( string $pattern , string $subject [, int $limit = -1 [, int $flags = 0 ]] )

分割して配列にする。

array preg_grep ( string $pattern , array $input [, int $flags = 0 ] )

指定された配列の要素のうち、パターンにマッチするものだけを返す。

## string preg_quote ( string $str [, string $delimiter = NULL ] )
正規表現構文の特殊文字の前にバックスラッシュを挿入します。 この関数は、実行時に生成される文字列をパターンとしてマッチングを行う必要があり、 その文字列には正規表現の特殊文字が含まれているかも知れない場合に有用です。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?