2

すべての角かっこが正しく開始および終了していることを確認し、数式であるかどうかを特定の文字列で確認したいと思います。

元 :

$str1 = "(A1+A2*A3)+A5+(B3^B5)*(C1*((A3/C2)+(B2+C1)))"

$str2 = "(A1+A2*A3)+A5)*C1+(B3^B5*(C1*((A3/C2)+(B2+C1)))"

$str3 = "(A1+A2*A3)+A5++(B2+C1)))"

$str4 = "(A1+A2*A3)+A5+(B3^B5)*(C1*(A3/C2)+(B2+C1))"

上記の例$str1$str4は、有効な文字列です。

助けてください....

4

3 に答える 3

2

一種のパーサーが必要になります。括弧と入れ子の可能性のあるものの量と順序を確認する必要があるため、正規表現ではこれを処理できないと思います。以下のこのクラスは、私が見つけた括弧のPythonベースの数学式構文バリデーターのクイックPHPポートです。

class MathExpression {

    private static $parentheses_open = array('(', '{', '[');
    private static $parentheses_close = array(')', '}', ']');

    protected static function getParenthesesType( $c ) {
        if(in_array($c,MathExpression::$parentheses_open)) {
            return array_search($c, MathExpression::$parentheses_open);
        } elseif(in_array($c,MathExpression::$parentheses_close)) {
            return array_search($c, MathExpression::$parentheses_close);
        } else {
            return false;
        }
    }

    public static function validate( $expression ) {
        $size = strlen( $expression );
        $tmp = array();
        for ($i=0; $i<$size; $i++) {
            if(in_array($expression[$i],MathExpression::$parentheses_open)) {
                $tmp[] = $expression[$i];
            } elseif(in_array($expression[$i],MathExpression::$parentheses_close)) {
                if (count($tmp) == 0 ) {
                    return false;
                }
                if(MathExpression::getParenthesesType(array_pop($tmp)) 
                    != MathExpression::getParenthesesType($expression[$i])) {
                    return false;
                }
            }
        }
        if (count($tmp) == 0 ) {
            return true;
        } else {
            return false;
        }
    }
}

//Mathematical expressions to validate
$tests = array(
    '(A1+A2*A3)+A5+(B3^B5)*(C1*((A3/C2)+(B2+C1)))',
    '(A1+A2*A3)+A5)*C1+(B3^B5*(C1*((A3/C2)+(B2+C1)))',
    '(A1+A2*A3)+A5++(B2+C1)))',
    '(A1+A2*A3)+A5+(B3^B5)*(C1*(A3/C2)+(B2+C1))'
);

// running the tests...
foreach($tests as $test) {
    $isValid = MathExpression::validate( $test );
    echo 'test of: '. $test .'<br>';
    var_dump($isValid);
}
于 2013-02-02T11:44:30.707 に答える
1

さて、あなたが探しているのは、文脈自由文法 またはプッシュダウンオートマトンだと思います。正規表現だけではできません。(少なくとも、簡単で良い方法はありません)

これは、ネストされた構造を扱っているためです。実装のいくつかのアイデアはここにありますセミコロンで終了したC++for&whileループを検出するための正規表現

于 2013-02-02T11:59:36.450 に答える
-1

開き角かっこと閉じかっこがいくつあるかを返す正規表現を使用しますか?

次に、両方の中括弧の数を確認します。等しい場合は式が正しく、そうでない場合は間違っています。

于 2013-02-02T11:11:07.483 に答える