1

文字列を指定して、単語が最初に出現した後に発生するすべてのものに一致させます。単語は、括弧のペア内のどこにも表示されてはなりませんが、他の単語は表示されます。例えば:

SELECT
t1.col1,
(SELECT t2.col1 FROM table2 t2
    WHERE t2.id IN(SELECT * FROM table5 WHERE id = t2.id)
) AS alias1,
t1.col2
----------
FROM
table1 t1,
(SELECT id FROM table3 t3 WHERE t3.id = t1.table3_id) t3,
table4 t4

点線の後のすべてを探しています。具体的にはFROM、括弧内のどこにも表示されない単語が最初に出現した後のすべてです。

正規表現が機能しない場合は、解析するPHPステートメントを作成します。私もそれで大変な時間を過ごしています、トー!私はこれを行うと思います、私は単語と括弧で文字列をトークン化する必要がありますか?

4

2 に答える 2

1

ネストされた親が含まれる場合、正規表現は悪名高いほど難しい(または不可能)可能性があるため、ここでは正規表現が最善の解決策ではない可能性があると思います。

また、各文字をループすることは、多くの不要なループが発生するため、最善のアプローチではないと思います。

これが最善のアプローチだと思います。

特定の文字列の各出現を検索し、その出現前の親の数を数えます。開始親の数が終了親の数と等しい場合、正しい一致があります。これにより、ループが大幅に減少し、実際にチェックする意味をチェックするだけになります。

findWordこのアプローチをとる関数を作りました。$inこれは、SQLステートメントがで$searchある例で機能します'FROM'

function findWord( $in, $search ) {

    if( strpos($in, $search) === 0 ) return $in;

    $before = '';
    while( strpos($in, $search, 1) ) {
        $i = strpos($in, $search, 1);
        $before .= substr($in, 0, $i);
        $in = substr($in, $i);

        $count = count_chars($before);

        if( $count[40] == $count[41] )
            return $in;
    }

    return false;
}
于 2013-02-04T06:41:50.377 に答える
0

誰かがより良い答えを持っていない限り、私はプログラム的なアプローチで行きます。

/**
 * Find the portion of the SQL statement occurring after
 * the first occurrence of the word 'FROM' (which itself
 * does not appear within parens)
 */
public static function sql_after_from($sql) {
    $arr = str_split($sql);
    $indent = 0;
    $out = '';
    $start = 0;
    $len = count($arr);
    for($x=0; $x < $len; $x++) {
        $c = $arr[$x]; //current character
        if($c == '(') $indent++;
        if($c == ')') $indent--;
        $out .= $arr[$x];
        //do the last 4 letters spell FROM?
        if(substr($out, $x-3, $x) == 'FROM') {
            if($indent == 0) { //not anywhere within parens
                $start = $x+2;
                break; //go no further 
            }
        }
    }
    //everything after the first occurrence of FROM
    return substr($sql, $start);
}
于 2013-02-04T05:14:21.833 に答える