2010-09-25 88 views
2

我想做一個RegExp匹配與MySQL針對一個變量,像這樣:用正則表達式直接處理整個「單詞」?

SELECT * 
    FROM table 
WHERE table.CONTENT 
REGEXP CONCAT('([[:space:]]|[[:punct:]])', table.NAME, '([[:space:]]|[[:punct:]])') 

這工作得很好,但它可能table.NAME有在它的正則表達式的特殊字符(如「|」),在這種情況下,它全部搞砸了。是否有一個正則表達式運算符會直接處理整個字符序列並忽略其中的運算符?例如,如果table.NAME是'left | right'的一行,我希望它只匹配如果table.CONTENT字面上的字符串'left | right'在其中。但除非我能夠以某種方式強制執行,否則MySQL會將其視爲運營商並查找「左」或「右」。

+0

您是否知道REGEXP比'LIKE'慢?如果你想要更好的性能,我建議使用不涉及特殊字符的命名方案。 – 2010-09-25 00:31:06

回答

0

您的字符串應該有管道字符反斜槓轉義用於正則表達式。我看不出有任何MySQL的功能,專爲逃避正則表達式字符串,但你可以嘗試使用REPLACE添加反斜線:

REPLACE(table.NAME, '|', '\|') 
+0

沒錯,但那只是一個操作員。我必須這樣做,以取代每個運算符(。,?,+,*等)以避免它們。我正在尋找'^%這兩個符號之間的所有運算符都被當作文字字符%$'處理;開始看起來不存在... – NChase 2010-09-25 12:12:31

0

這是一個很好的問題。

更換特殊字符是無止境的...所以你可能在你的字符串都逃不過

你可以這樣做:

 
DELIMITER // 
DROP FUNCTION myescape; 
CREATE FUNCTION myescape(str varchar(255)) 
    RETURNS TEXT 
    LANGUAGE SQL 
BEGIN 
    DECLARE strLen INT DEFAULT 0; 
    DECLARE i   INT DEFAULT 0; 
    DECLARE newStr varchar(255) DEFAULT ''; 
     SET strLen = LENGTH(str); 

do_this: 
    LOOP 
     SET i = i+1; 
     SET newStr = CONCAT(newStr,'\\',SUBSTRING(str,i,1)); 

    IF strLen = i THEN 
     LEAVE do_this; 
    END IF; 
    END LOOP do_this; 
    RETURN newStr; 
END; 

// 
DELIMITER ; 

此功能逃避你的字符串的所有字符。所以你可以把它插入你的REGEXP。

 
REGEXP CONCAT('([[:space:]]|[[:punct:]])', myescape(table.NAME), '([[:space:]]|[[:punct:]])') 

告訴我們,如果它回答你的問題。

祝您的項目順利。