3

私は正規表現にかなり慣れていません。私がそのような文字列を持っているとしましょう:

UPDATE table_name SET column = :column WHERE column IN(:column_32, :column_34, :column_347)

そして、私が配列を持っていると仮定します:

$arr = array(
    'column' => 'Test',
    'column_32' => 'Tester',
    'column_34' => 'Faux data',
    'column_347' => 'Column data'
);

私がやりたいのは、プレースホルダー(:column、:column_32など)を配列内の対応する値に置き換えることです。問題は、:columnを「Test」に置き換えると:column_32が:Test_32になるため、str_replaceはそれをカットしないことです。

それで、私はいくつかのカスタム正規表現を書き始めました。これが私が実行しているテストスクリプトです:

foreach($arr as $k => $v){
    var_dump(preg_match_all('(:'.$v.'[^_])', $str, $matches));
}

正しい文字列と一致します。問題は、一致の一部として「、」と「)」も返すことです。私はここで何かを見落としていますか?

4

3 に答える 3

3

これは少しハックかもしれませんが、配列をキーの長さで最長から最短に並べ替えてみてはどうでしょうか。次に、別のキーの部分文字列になる可能性のあるキーは、それを含む文字列の後にチェックされます。したがって、次のように配列を並べ替えます。

$arr = array(
    'column_347' => 'Column data'
    'column_32' => 'Tester',
    'column_34' => 'Faux data',
    'column' => 'Test',
);

もちろん、これを自動的に行うこともできます。PHP 5.3.0 以降では、次のようになります。

uksort($arr, function($a, $b) {
    if(strlen($a) > strlen($b))
        return -1;
    else
        return 0;
});

5.3.0 未満では、次のいずれかを使用できます (PHP 4.0.1 以降):

uksort($arr, create_function('$a, $b', '
    if(strlen($a) > strlen($b))
        return -1;
    else
        return 0;
'));

または (nice 匿名関数構文を使用できない場合、または 4.0.1 より前の PHP を使用している場合は、おそらくこれが望ましいでしょう):

function compare($a, $b) {
    if(strlen($a) > strlen($b))
        return -1;
    else
        return 0;
}

uksort($arr, "compare");
于 2012-11-26T15:49:35.233 に答える
2

_基本的に、キーワードの後のすべての非文字を避けています。[^_]変数が「アンダースコアではない単一の文字を見つける」ことを意味するため、正規表現はコンマと閉じ括弧を正しく取得します。

識別子を見つけてみませんか?:column_347たとえば、検索しても問題ありません。プレースホルダーの後に単語境界を検索して、正規表現に「これ (列など) が完全な単語でない場合は停止しないでください。

これは、単語境界である を[^_]に置き換えて取得されます。このリンクは、これがどのように機能するかを示しています。正規表現は最初の「列」のみに一致することに注意してください\b

于 2012-11-26T15:51:46.577 に答える
2

PDOこれはあなたの正規表現の質問には答えませんが、とにかく実装を提供したかったのです:

<?php

    $sql = 'UPDATE table_name SET column = :column WHERE column IN(:column_32, :column_34, :column_347)'

    $arr = array(
        'column' => 'Test',
        'column_32' => 'Tester',
        'column_34' => 'Faux data',
        'column_347' => 'Column data'
    );

    $sth = $dbh->prepare($sql);

    foreach ($arr as $k => $v) {
        $sth->bindParam(':' . $k, $v);
    }

    $sth->execute();

?>

他の誰かのコードで作業していて、 を知らなかっPDOた場合、多くの理由 (インジェクション攻撃に対する保護を含む) から、これがおそらく正しい方法です。ただし、PDO代替の正規表現ベースの実装を知っていて、とにかくそれを望んでいる場合は、@m.buettner と @Gabber の両方が適切なアドバイスを提供します。

于 2012-11-26T16:00:43.700 に答える