0

この質問の重複が見つからなかったのは驚きです。いくつかのSQL文字列を解析して、最初の「SELECT...FROM」文字列を別の文字列に置き換えようとしています。それほど難しいことではないと思いますが、まだ解決策を見つけていません。テスト文字列が次の場合:

' SELECT something, something_else FROM (SELECT somebody FROM some_table)'

そして私はそれを次のように置き換えたいと思います:

' SELECT count(*) as total FROM (SELECT somebody FROM some_table)'

REReplaceNoCase()を使用して次の正規表現を試しました。

<cfset SQL = #REReplaceNoCase(test, "^\s*(SELECT.*\s+FROM\s)??", "SELECT count(*) as total FROM ")# />

<cfset SQL = #REReplaceNoCase(test, "^\s*SELECT.*(\s+FROM\s)??", "SELECT count(*) as total FROM ")# />
<cfset SQL = #REReplaceNoCase(test, "^\s*SELECT.*\s+(FROM)??\s", "SELECT count(*) as total FROM ")# />

だけでなく、他のいくつかのバリエーション。提案?

4

1 に答える 1

3

ここではreplaceを使用しません-最初のFROMを見つけて、その時点で文字列を2つの部分に分割し、新しい文字列を前面に追加する方が簡単(かつ効率的)です。

<cfsavecontent variable="Sql">
    SELECT something, something_else 
    FROM (SELECT somebody FROM some_table)
</cfsavecontent>

<cfset Sql = Sql.split( '(?=\bFROM\b)' , 2 ) />

<cfset Sql = 'SELECT count(*) as total ' & Sql[2] />

<cfdump var=#Sql# />

正規表現は先読みを使用するため、FROMの前の位置と一致し、再度追加する必要はありません。

もちろん、必要に応じて、分割に使用される正規表現を変更できます。

たとえば、大文字と小文字を区別せず、単語の境界ではなくスペースを使用するには、次のようにします。

.split( '(?i)(?=\sFROM\s)' , 2 )

2番目の引数(2)は、2つの文字列が含まれた後にsplitに停止するように指示するものです(したがって、2番目の配列項目にはFROMがさらにある場合でも、残りの文字列が含まれます)。

また、これはJavaの分割方法であり、正規表現にjava.util.regexを使用していることにも注意してください(CFのApache ORO正規表現とはいくつかの違い/改善があります)。

于 2012-11-07T18:54:13.607 に答える