OR条件(または) | PHPの正規表現

基本サンプル

正規表現でOR条件を実現にするには「|」を記述する。
/文字1|文字2/
文字1または文字2に一致

サンプル1
	$tests[] = "大きなネコと小さなイヌがいました。";
	$tests[] = "大きなネコがいました。";
	$tests[] = "小さなイヌがいました。";
	$tests[] = "普通サイズのヤギがいました。";
	
	foreach($tests as $test){
		if(preg_match('/イヌ|ネコ/', $test)){
			echo $test.'→'.'○<br>';
		}else{
			echo $test.'→'.'×<br>';
		}
	}
	
出力
	大きなネコと小さなイヌがいました。→○
	大きなネコがいました。→○
	小さなイヌがいました。→○
	普通サイズのヤギがいました。→×
	


応用サンプル

文字列に日付が含まれているか調べる正規表現のサンプル。
日付のセパレータは「/」、「-」、「年月日」などがある。
OR条件を応用して、これら複数のセパレータに対応してみる。


サンプル2
	$tests=null;
	$tests[] = "いろは2016-6-6ネコ";
	$tests[] = "いろは2016/6/6イヌ";
	$tests[] = "いろは2016年6月6日ヤギ";
	$tests[] = "いろは";

	foreach($tests as $test){
		$re = '/([1-9][0-9]{3})¥/|-|年([1-9]{1}|1[0-2]{1})¥/|-|月([1-9]{1}|[1-2]{1}[0-9]{1}|3[0-1]{1})/';
		if(preg_match($re, $test)){
			echo $test.'→'.'○<br>';
		}else{
			echo $test.'→'.'×<br>';
		}
	}
	
	いろは2016-6-6ネコ→○
	いろは2016/6/6イヌ→○
	いろは2016年6月6日ヤギ→○
	いろは→×
	


正規表現で文字列から日付を抜き出す

日付は様々な表記方法、月により変わる日数(28日~31日)、閏年などがあり複雑である。
そのため、正規表現だけで完全な日付を抜き出すとなると、かなり冗長で複雑になる。
よって正規表現の日付に関してはある程度の妥協が必要になってくる。

サンプル1

シンプルな正規表現。広い範囲の日付書式を取得できる。しかし、99月99日なんていうのも取れてしまう。
/([0-9]{4})(\/|-|年)([0-9]{1,2})(\/|-|月)([0-9]{1,2})/



出力
	いろは2016-6-6ネコ → 2016-6-6
	いろは2016-06-06タヌキ → 2016-06-06
	いろは2016-12-31ロバ → 2016-12-31
	いろは9999-99-99ブタ → 9999-99-99
	いろは2016/6/6イヌ → 2016/6/6
	いろは2016年6月6日ヤギ → 2016年6月6
	いろは2016-6カニ → 一致なし
	いろは2016カニ → 一致なし
	いろは → 一致なし
	


サンプル2

サンプル1より少し厳密に日付を取得できるが、6月31日(6月は30日まで)など存在しない日付の値まで取得できてしまう。
どうせ完全な日付が取得できないのであれば、サンプル1で採用し、バリデーション処理を自前で書いたほうが効率がよいかもしれない。
/([1-9][0-9]{3})\/|-|年([1-9]{1}|1[0-2]{1})\/|-|月([1-9]{1}|[1-2]{1}[0-9]{1}|3[0-1]{1})/



出力
	いろは2016-6-6ネコ → 2016-6-6
	いろは2016-6-31 → 2016-6-31
	いろは2016-06-06タヌキ → 2016-06-06
	いろは2016-12-31ロバ → 2016-12-31
	いろは9999-99-99ブタ → 一致なし
	いろは2016/6/6イヌ → 2016/6/6
	いろは2016年6月6日ヤギ → 2016年6月6
	いろは2016-6カニ → 一致なし
	いろは2016カニ → 一致なし
	いろは → 一致なし
	


様々な一致条件

検証

preg_match 関数に様々な正規表現を指定して、それぞれの一致を検証する。

あいうえお9aabbc123
x:正規表現 一致 説明
/あ/ 「あ」が文字列中に含まれているか
/い/ 「い」が文字列中に含まれているか
/12/ 「12」が文字列中に含まれているか
/^あ/ 先頭は「あ」であるか
/^い/ × 先頭は「い」であるか
/3$/ 末尾は「3」であるか
/2$/ × 末尾は「2」であるか
/\d[1]$/ × 末尾は数値か(1連続)
/\d[2]$/ × 末尾は2連続の数値か
/\d[3]$/ 末尾は3連続の数値か
/\d[4]$/ × 末尾は4連続の数値か
/\d[1,2]$/ × 末尾の1-2番目に数値が含まれているか
/\d[1,3]$/ 末尾の1-3番目に数値が含まれているか
/\d[1,4]$/ × 末尾の1-4番目に数値が含まれているか
/^\d[1,4]/ × 先頭の1-4番目に数値が含まれているか
/a[2]/ × 「aa」が含まれているか
/a[3]/ × 「aaa」が含まれているか
/\w/ 「A-Za-z0-9_」が含まれているか
/^\d+$/ × すべて数値か
/^\w+$/ × すべて半角英数字か
/^[ぁ-んァ-ン]+\w+$/ 前半はかな(カタカナも含む)で後半は半角英数字であるか
/(^あい)(.*)(23$)/ 「あい」と「23」で挟まれているか?
/d{2,8}/ 2~8桁の連続する数値が含まれているか?

検証2

文字列 /^insert\s/i /;$/ /(^INSERT\s)(.*)(;$)/i
INSERT id,name,val (111,'test',9);
INSERT id,name,val (111,'test',9) × ×
(222,'test',9); × ×

検証

' ( ) ' で挟まれた文字を取得する

ソースコード
	<?php 
	$str ="ヒージャー(やぎ)を散歩する";
	$re = '/(\()(.*)(\))/';
	preg_match($re, $str,$match);
	$str2=null;
	if(!empty($match[2])){
		$str2 = $match[2];
	}
	echo $str2;
	?>
	

echo出力
やぎ



ファイル名のバリデーション

ファイル名に含まれてはならない記号をいくつかバリデーションではじく正規表現。

ソースコード
	if(preg_match('/;|<|>|%|\$|\.\/|\\\\/', 'xxx.png')){
		echo 'err<br>';
	}else{
		echo 'ok<br>';
	}
	
出力
	ok



ワイルドカード検索

例1

正規表現:赤い.*エサ
		大きな赤い猫にエサを与える
		小さな赤い犬にエサを与えてみた。
	

例2:「 ( 」が含まれる場合

正規表現:¥(length=.*)
		var str1 = '123' (length=3) // test
		test_data (length=10) // test
	



XMLタグから不要な空白を除去


	$xml_str= "< animal  >< cat  >赤い猫<cat  >< dog>灰色の犬</ dog>< /  animal >";
	$xml_str = preg_replace('/<¥s+/','<',$xml_str);
	$xml_str = preg_replace('/<¥/¥s+/','</',$xml_str);
	$xml_str = preg_replace('/¥s+>/','>',$xml_str);
	var_dump($xml_str);// → '<animal><cat>赤い猫<cat><dog>灰色の犬</dog></animal>'
	


半角英数字(一部記号)のチェック


	$strs = [];
	$strs[] = "abc-123_5.csv";
	$strs[] = "ねこ";
	$strs[] = "cat";
	$strs[] = 987;
	$strs[] = "";
	$strs[] = '-_';
	$strs[] = 'abcあ';
	
	foreach($strs as $str){
		echo $str;
		if (preg_match("/^[a-zA-Z0-9-_.]+$/", $str)) {
			echo "¥t〇<br>";
		} else {
			echo "¥t×<br>";
		}
	}
	

出力

abc-123_5.csv	〇
ねこ ×
cat 〇
987 〇
×
-_ 〇
abcあ ×