preg_match
(PHP 4, PHP 5, PHP 7, PHP 8)
preg_match — 正規表現によるマッチングを行う
説明
string
$pattern
,string
$subject
,array
&$matches
= null
,int
$flags
= 0,int
$offset
= 0): int|false
pattern
で指定した正規表現により
subject
を検索します。
パラメータ
pattern
-
検索するパターンを表す文字列。
subject
-
入力文字列。
matches
-
matches
を指定した場合、検索結果が代入されます。 $matches[0] にはパターン全体にマッチしたテキストが代入され、 $matches[1] には 1 番目のキャプチャ用サブパターンにマッチした 文字列が代入され、といったようになります。 flags
-
flags
には以下のフラグの組み合わせを指定できます。PREG_OFFSET_CAPTURE
-
このフラグを設定した場合、各マッチに対応する文字列のオフセットも(バイト単位で)返されます。 これは、
matches
の値を配列に変更することに注意してください。 その配列のすべての要素は、 オフセット0
で一致した文字列、 およびその文字列のオフセット1
でのsubject
へのオフセットからなります。<?php
preg_match('/(foo)(bar)(baz)/', 'foobarbaz', $matches, PREG_OFFSET_CAPTURE);
print_r($matches);
?>上の例の出力は以下となります。
Array ( [0] => Array ( [0] => foobarbaz [1] => 0 ) [1] => Array ( [0] => foo [1] => 0 ) [2] => Array ( [0] => bar [1] => 3 ) [3] => Array ( [0] => baz [1] => 6 ) )
PREG_UNMATCHED_AS_NULL
-
このフラグが渡されると、マッチしなかったサブパターンは
null
として通知されます。 渡されなかった場合、空の string として通知されます。<?php
preg_match('/(a)(b)*(c)/', 'ac', $matches);
var_dump($matches);
preg_match('/(a)(b)*(c)/', 'ac', $matches, PREG_UNMATCHED_AS_NULL);
var_dump($matches);
?>上の例の出力は以下となります。
array(4) { [0]=> string(2) "ac" [1]=> string(1) "a" [2]=> string(0) "" [3]=> string(1) "c" } array(4) { [0]=> string(2) "ac" [1]=> string(1) "a" [2]=> NULL [3]=> string(1) "c" }
offset
-
通常、検索は対象文字列の先頭から開始されます。 オプションのパラメータ
offset
を使用して 検索の開始位置を (バイト単位で) 指定することも可能です。注意:
offset
を用いるのと、substr($subject, $offset)
を preg_match()の対象文字列として指定するのとは 等価ではありません。 これは、pattern
には、 ^, $ や (?<=x) のような言明を含めることができるためです。 以下を比べてみてください。<?php
$subject = "abcdef";
$pattern = '/^def/';
preg_match($pattern, $subject, $matches, PREG_OFFSET_CAPTURE, 3);
print_r($matches);
?>上の例の出力は以下となります。
Array ( )
一方、この例を見てください。
<?php
$subject = "abcdef";
$pattern = '/^def/';
preg_match($pattern, substr($subject,3), $matches, PREG_OFFSET_CAPTURE);
print_r($matches);
?>出力は以下のようになります。
Array ( [0] => Array ( [0] => def [1] => 0 ) )
substr() 関数を利用しない別の方法として、
^
アンカーではなく、 言明\G
またはA
修正子を使う方法があります。 これらは両方ともoffset
パラメータとともに動作します。
戻り値
preg_match() は、pattern
が指定した subject
にマッチした場合に 1 を返します。
マッチしなかった場合は 0 を返します。
失敗した場合に false
を返します
エラー / 例外
渡された正規表現のパターンがコンパイルできない場合、E_WARNING
が発生します。
例
例1 文字列 "php" を探す
<?php
// パターンのデリミタの後の "i" は、大小文字を区別しない検索を示す
if (preg_match("/php/i", "PHP is the web scripting language of choice.")) {
echo "A match was found.";
} else {
echo "A match was not found.";
}
?>
例2 単語 "web" を探す
<?php
/* パターン内の \b は単語の境界を示す。このため、独立した単語の
* "web"にのみマッチし、"webbing" や "cobweb" のような単語の一部にはマッチしない */
if (preg_match("/\bweb\b/i", "PHP is the web scripting language of choice.")) {
echo "A match was found.";
} else {
echo "A match was not found.";
}
if (preg_match("/\bweb\b/i", "PHP is the website scripting language of choice.")) {
echo "A match was found.";
} else {
echo "A match was not found.";
}
?>
例3 URL からドメイン名を得る
<?php
// get host name from URL
preg_match('@^(?:http://)?([^/]+)@i',
"http://www.php.net/index.html", $matches);
$host = $matches[1];
// get last two segments of host name
preg_match('/[^.]+\.[^.]+$/', $host, $matches);
echo "domain name is: {$matches[0]}\n";
?>
上の例の出力は以下となります。
domain name is: php.net
例4 名前つきサブパターンの使用法
<?php
$str = 'foobar: 2008';
preg_match('/(?P<name>\w+): (?P<digit>\d+)/', $str, $matches);
/* 別のやり方 */
// preg_match('/(?<name>\w+): (?<digit>\d+)/', $str, $matches);
print_r($matches);
?>
上の例の出力は以下となります。
Array ( [0] => foobar: 2008 [name] => foobar [1] => foobar [digit] => 2008 [2] => 2008 )
注意
ある文字列が他の文字列内に含まれているかどうかを調べるためだけに preg_match() を使うのは避けた方が良いでしょう。 strpos() 関数を使うほうが速くなります。
参考
- PCRE のパターン
- preg_quote() - 正規表現文字をクオートする
- preg_match_all() - 繰り返し正規表現検索を行う
- preg_replace() - 正規表現検索および置換を行う
- preg_split() - 正規表現で文字列を分割する
- preg_last_error() - 直近の PCRE 正規表現処理のエラーコードを返す
- preg_last_error_msg() - 最後に実行した PCRE 正規表現に関するエラーメッセージを返す
User Contributed Notes 51 notes
Simple regex
Regex quick reference
[abc] A single character: a, b or c
[^abc] Any single character but a, b, or c
[a-z] Any single character in the range a-z
[a-zA-Z] Any single character in the range a-z or A-Z
^ Start of line
$ End of line
\A Start of string
\z End of string
. Any single character
\s Any whitespace character
\S Any non-whitespace character
\d Any digit
\D Any non-digit
\w Any word character (letter, number, underscore)
\W Any non-word character
\b Any word boundary character
(...) Capture everything enclosed
(a|b) a or b
a? Zero or one of a
a* Zero or more of a
a+ One or more of a
a{3} Exactly 3 of a
a{3,} 3 or more of a
a{3,6} Between 3 and 6 of a
options: i case insensitive m make dot match newlines x ignore whitespace in regex o perform #{...} substitutions only once
There does not seem to be any mention of the PHP version of switches that can be used with regular expressions.
preg_match_all('/regular expr/sim',$text).
The s i m being the location for and available switches (I know about)
The i is to ignore letter cases (this is commonly known - I think)
The s tells the code NOT TO stop searching when it encounters \n (line break) - this is important with multi-line entries for example text from an editor that needs search.
The m tells the code it is a multi-line entry, but importantly allows the use of ^ and $ to work when showing start and end.
I am hoping this will save someone from the 4 hours of torture that I endured, trying to workout this issue.
Sometimes its useful to negate a string. The first method which comes to mind to do this is: [^(string)] but this of course won't work. There is a solution, but it is not very well known. This is the simple piece of code on how a negation of a string is done:
(?:(?!string).)
?: makes a subpattern (see http://www.php.net/manual/en/regexp.reference.subpatterns.php) and ?! is a negative look ahead. You put the negative look ahead in front of the dot because you want the regex engine to first check if there is an occurrence of the string you are negating. Only if it is not there, you want to match an arbitrary character.
Hope this helps some ppl.