2009-04-07 9 views
1

我正在尋找一種不顯眼的方式來查找和替換表名,這是基於它們在SQL查詢中的位置。PHP - 在SQL中預定義表名的正則表達式

例子:

$query = 'SELECT t1.id, t1.name, t2.country FROM users AS t1, country AS t2 INNER JOIN another_table AS t3 ON t3.user_id = t1.id'; 

我基本上是需要預先設置客戶端名稱的縮寫表名,然後有我的CMS處理這種變化。因此,從'用戶'到'so_users'(如果Stack Overflow是一個客戶端),但不必在所有查詢表名稱(如Drupal)中添加大括號。一個例子就是WordPress如何讓你在設置時預先指定表名,但WordPress處理這個問題的方式對我而言並不理想。

對於我的例子,我想一些方法的輸出是:

$query = 'SELECT t1.id, t1.name, t2.country FROM so_users AS t1, so_country AS t2 INNER JOIN so_another_table AS t3 ON t3.user_id = t1.id'; 

(在表名前綴 'SO_')

謝謝。

克里斯

+0

重複http://stackoverflow.com/questions/453975/php-regex-logic-for-prepending-table-names – 2009-04-07 17:29:43

+0

不是重複的。 – chaos 2009-04-07 17:33:02

回答

1

使用查詢構建器類將是最好的解決辦法,因爲你不想讓你想用正則表達式替換模式中的任何假設。如果您沒有找到適合您特定需求的現有庫,請推出自己的庫。製作簡單的查詢生成器並不困難。

1

這應該適用於您給出的示例。

雖然正如其他人所提到的一樣,Regexes並不是您需要的最佳工具。鑑於正則表達式適用於您的示例,僅此而已,無所不及。有很多可以想象的SQL構造,其中這個正則表達式將而不是作出你需要的替換。

$result = preg_replace('/(FROM|JOIN|,) ([_\w]*) (AS)/m', '$1 so_$2 $3', $subject); 

# (FROM|JOIN|,) ([_\w]*) (AS) 
# 
# Match the regular expression below and capture its match into backreference number 1 «(FROM|JOIN|,)» 
# Match either the regular expression below (attempting the next alternative only if this one fails) «FROM» 
#  Match the characters 「FROM」 literally «FROM» 
# Or match regular expression number 2 below (attempting the next alternative only if this one fails) «JOIN» 
#  Match the characters 「JOIN」 literally «JOIN» 
# Or match regular expression number 3 below (the entire group fails if this one fails to match) «,» 
#  Match the character 「,」 literally «,» 
# Match the character 「 」 literally « » 
# Match the regular expression below and capture its match into backreference number 2 «([_\w]*)» 
# Match a single character present in the list below «[_\w]*» 
#  Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*» 
#  The character 「_」 «_» 
#  A word character (letters, digits, etc.) «\w» 
# Match the character 「 」 literally « » 
# Match the regular expression below and capture its match into backreference number 3 «(AS)» 
# Match the characters 「AS」 literally «AS» 
+0

嘿, 非常感謝您的解決方案。我只是測試你的代碼,它的工作。只有一個表名錯過了。 '國家'表沒有變成'so_country'。有什麼建議麼? 克里斯 – Torez 2009-04-07 18:27:04

1

正則表達式無法解析SQL。想想像這樣的結構:

SELECT 'SELECT * FROM users'; 
SELECT * FROM users; -- users 
SELECT '* -- users' FROM users; 
SELECT '\' FROM users; -- ';    -- differs in My/Pg vs others 
SELECT users.name FROM country AS users; -- or without AS 
SELECT users(name) FROM country;   -- users() is procedure 
SELECT "users"."name" FROM users;   -- or ` on MySQL, [] in TSQL 

等等。爲了解析SQL,你需要一個合適的SQL解析器庫;在正則表達式中試圖破解它只會造成奇怪的錯誤。