web-dev-qa-db-ja.com

文字列が正規表現であるかどうかをテストします

文字列がPHPの正規表現または通常の文字列であるかどうかをテストする良い方法はありますか?

理想的には、trueまたはfalseを返す文字列を実行する関数を記述したいと思います。

preg_last_error()を見ました:

_<?php
preg_match('/[a-z]/', 'test');
var_dump(preg_last_error());
preg_match('invalid regex', 'test');
var_dump(preg_last_error());
?>
_

明らかに最初のものはエラーではなく、2番目のものはエラーです。ただし、preg_last_error()は両方の時間で_int 0_を返します。

何か案は?

21
Hosh Sadiq

正規表現がPHPで有効かどうかをテストする唯一の簡単な方法は、正規表現を使用して、警告がスローされるかどうかを確認することです。

ini_set('track_errors', 'on');
$php_errormsg = '';
@preg_match('/[blah/', '');
if($php_errormsg) echo 'regex is invalid';

ただし、任意のユーザー入力を正規表現として使用することは悪い考えです。以前はPCREエンジンにセキュリティホール(バッファオーバーフロー=>リモートコード実行)があり、コンパイル/実行に大量のCPU /メモリを必要とする特別に細工された長い正規表現を作成できる可能性があります。

8
ThiefMaster

方法の良い答えは次のとおりです。

https://stackoverflow.com/a/12941133/251907

if(@preg_match($yourPattern, null) === false){
    //pattern is broken
}else{
    //pattern is real
}
12
ya_dimon

文字列が正規表現であるかどうかをテストする最も簡単な方法は次のとおりです。

if( preg_match("/^\/.+\/[a-z]*$/i",$regex))

これにより、文字列が正規表現として意図されている可能性が高いかどうかがわかります。ただし、そのチェックに合格しても正規表現に失敗する文字列は多数あります。中央のエスケープされていないスラッシュ、最後の不明な修飾子、不一致の括弧などはすべて問題を引き起こす可能性があります。

理由 preg_last_error返された0は、「無効な正規表現」が次のようになっていないためです。

  • PREG_INTERNAL_ERROR(内部エラー)
  • PREG_BACKTRACK_LIMIT_ERROR(過度にバックトラックを強制する)
  • PREG_RECURSION_LIMIT_ERROR(過度に再帰的)
  • PREG_BAD_UTF8_ERROR(フォーマットが不適切なUTF-8)
  • PREG_BAD_UTF8_OFFSET_ERROR(UTF-8文字の途中にオフセット)
12

なぜ...別の正規表現を使用しないのですか? 3行、@の応急修理などはありません:

// Test this string
$str = "/^[A-Za-z ]+$/";

// Compare it to a regex pattern that simulates any regex
$regex = "/^\/[\s\S]+\/$/";

// Will it blend?
echo (preg_match($regex, $str) ? "TRUE" : "FALSE");

または、関数形式では、さらにきれいになります。

public static function isRegex($str0) {
    $regex = "/^\/[\s\S]+\/$/";
    return preg_match($regex, $str0);
}

これは妥当性をテストしません。しかし、質問はIs there a good way of test if a string is a regex or normal string in PHP?のようで、それを実行します。

10
Ben