Skip to content

Instantly share code, notes, and snippets.

@soyoes
Last active September 20, 2016 03:56
Show Gist options
  • Save soyoes/d5643406b2173cf1e9c9c3afc523f4ac to your computer and use it in GitHub Desktop.
Save soyoes/d5643406b2173cf1e9c9c3afc523f4ac to your computer and use it in GitHub Desktop.
PHP 正規表現 上級編 ref: http://qiita.com/soyoes/items/231d2f22d61a5b67b4b9
$pattern = '/foo(?=bar)/';
preg_match($pattern,'Hello foo'); // BAD
preg_match($pattern,'Hello foobar'); // OK
$pattern = '/foo(?!bar)/';
preg_match($pattern,'Hello foo'); // OK
preg_match($pattern,'Hello foobar'); // BAD
preg_match($pattern,'Hello foo123'); // OK
[["how are"],["how"]]//1番
[["how are"],["how"]]//2番
null/3番
/(?<some_name>\w+) (?&some_name)/
body { color: #888; }
@media print { body { color: #333; } }
code { color: blue; }";
preg_match_all('/{.*?}/m',$css,$m1);
[
[
"{ color: #888; }",
"{ body { color: #333; }", //失敗 : {}は閉じていない
"{ color: blue; }"
]
]
/
{ # 1個目の '{'を検出
(?: # 抽出対象外のグループ.
[^{}]+ # '{' と '}'以外の文字列とマッチする場合は抽出.
| # そうでない場合は...
(?R) # 再帰コマンド、{}を発見した際に中身に対して繰り返して今の正規表現式でマッチングをかける。
)
* # 下の階層まで繰り返し
} # 閉じる記号の'}'までマッチングをかける。
/
preg_match_all('/{(?:[^{}]+|(?R))*}/m',$css,$m2);
[
[
"{ color: #888; }",
"{ body { color: #333; } }", //成功
"{ color: blue; }"
]
]
(?(condition)yes-pattern)
(?(condition)yes-pattern|no-pattern)
$pattern = '/(?(?=^\d{8}$)(\d{4})(\d{2})(\d{2})|(\d{4})\-(\d{2})\-(\d{2}))/';
preg_match_all($pattern, '20160911', $m);
preg_match_all($pattern, '2016-09-11', $m);
$ymd = !empty($m[1][0])? $m[1][0].$m[2][0].$m[3][0] : $m[4][0].$m[5][0].$m[6][0];
$pattern = '/(?<!foo)bar/';
preg_match($pattern,'Hello bar'); // OK
preg_match($pattern,'Hello foobar'); // BAD
$pattern = '/^(<)?[a-z]+(?(1)>)$/';
preg_match($pattern, '<test>'); //OK
preg_match($pattern, '<foo'); //BAD
preg_match($pattern, 'bar>'); //BAD
preg_match($pattern, 'hello'); //OK
//例 : ?pattern=*_*
//warningが発生
preg_match('/'.$_REQUEST['pattern'].'/', $text);
//OK
preg_match('/'.preg_quote($_REQUEST['pattern']).'/', $text);
//OK \Q\Eの組み合わせでpreg_quoteの効果を実現
preg_match('/\Q'.$_REQUEST['pattern'].'\E/', $text);
$s = "Bob said: Hi
Bboby said: Hi
Lucy said: How are you
Marry said: good, you?";
//non-capture, マッチするけど、結果$mに反映しない. しかもiなどのmode Modifiersを指定可能
$s = preg_match_all('/(?>bob|marry)\b.*?:(.*)/i', $s, $m);
//capture, マッチかつ結果$mに反映
$s = preg_match_all('/(bob|marry) said:(.*)/i', $s, $m);
$s = "Bob said: Hi
Bboby said: Hi
Lucy said: How are you
Marry said: good, you?";
$s = preg_match_all('/(?>bob|marry)\b.*?:(?<msg>.*)/i', $s, $m);
//$m['msg'] is [" Hi"," good, you?"]
//inline形式
$s = preg_match_all('/(?i)[a-z]/', $s, $m);
//modifier形式
$s = preg_match_all('/[a-z]/i', $s, $m);
$s = preg_match_all('/(?is-m)[a-z]/', $s, $m);
//iとsをONにして、mをoffにする
$s = preg_match_all('/(?i:[a-z])/', $s, $m);
//null,()内の1個目のbcで失敗すると次のbはマッチされない
preg_match_all('/a(?>bc|b)c/', 'abc', $m);
//matchされるパターン
//一発目で a(bc)cまでマッチングされるため、backtrackが発生しない、regexのエンジンはコレで終了
preg_match_all('/a(?>bc|b)c/', 'abcc', $m);
/*
一般的なgroupの場合は以下のようにbacktrackが発生
a(bc)c > abc : mismatch
a(b)c > abc : match
*/
preg_match_all('/a(bc|b)c/', 'abc', $m);
/*
一般的なgroupの場合は以下の4回に渡ってmatchすることになる
(b+)c > bbbbc : match
(b+)c > bbbc : match
(b+)c > bbc : match
(b+)c > bc : match
一方、(?>b+)cは最初の一回のみ
*/
preg_match_all('/(?>b+)c/', 'bbbbc', $m);
//(?1) : 1個目の()で囲まれるgroup、この例だと(?1)=\w+
preg_match_all('/(\w+) (?1)/', 'how are you', $m);
//(?-1) : 1個前の()で囲まれるgroup、この例だと(?-1)=1個前の\w+
preg_match_all('/(\w+) (?-1)/', 'how are you', $m);
//(?+1) : 1個後ろの()で囲まれるgroup、この例だと後ろのgroupはないので何もマッチされない
preg_match_all('/(\w+) (?+1)/', 'how are you', $m);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment