2010-02-04 106 views
4

我發現mysql的很奇怪的行爲。 的選擇如下返回0:在mysql中匹配正則表達式中的十六進制字符

SELECT CONVERT('a' USING BINARY) REGEXP '[\x61]' 

但是語義相同下面選擇返回1:

SELECT CONVERT('a' USING BINARY) REGEXP '[\x61-\x61]' 

你知道這裏發生了什麼? 我測試過在mysql 5.0.0.3031和4.1.22中

我需要十六進制字符來創建一個正則表達式,當二進制字符串在utf8中被編碼時匹配。這種正則表達式的perl版本可以在w3c site上找到。它看起來如下:

$field =~ 
     m/\A(
     [\x09\x0A\x0D\x20-\x7E]   # ASCII 
     | [\xC2-\xDF][\x80-\xBF]    # non-overlong 2-byte 
     | \xE0[\xA0-\xBF][\x80-\xBF]  # excluding overlongs 
     | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte 
     | \xED[\x80-\x9F][\x80-\xBF]  # excluding surrogates 
     | \xF0[\x90-\xBF][\x80-\xBF]{2}  # planes 1-3 
     | [\xF1-\xF3][\x80-\xBF]{3}   # planes 4-15 
     | \xF4[\x80-\x8F][\x80-\xBF]{2}  # plane 16 
    )*\z/x; 
+0

我刪除了'utf-8'標籤,因爲這個問題純粹是關於MySQL的正則表達式的。您的其他問題是處理UTF-8方面的問題:http://stackoverflow.com/questions/2199825/how-can-i-check-if-a-binary-string-is-utf-8-in -mysql – 2010-02-04 21:00:59

回答

2

這也很相配:

SELECT CONVERT('a' USING BINARY) REGEXP '[1-\x]' 

的原因是\x被interpeted爲xa1x之間。你的正則表達式的其餘部分只是普通字符,因爲它們已經在[1-x]範圍內,所以在這裏不相關。

SELECT CONVERT('0' USING BINARY) REGEXP '[\x61-\x61]' -- Fails, because 0 < 1. 
SELECT CONVERT('1' USING BINARY) REGEXP '[\x61-\x61]' -- Succeeds: inside [1-x]. 
SELECT CONVERT('2' USING BINARY) REGEXP '[\x61-\x61]' -- Succeeds: inside [1-x]. 
... 
SELECT CONVERT('w' USING BINARY) REGEXP '[\x61-\x61]' -- Succeeds: inside [1-x]. 
SELECT CONVERT('x' USING BINARY) REGEXP '[\x61-\x61]' -- Succeeds: inside [1-x]. 
SELECT CONVERT('y' USING BINARY) REGEXP '[\x61-\x61]' -- Fails, because y > x. 

我不知道你想達到什麼樣的,但是如果你想要的十六進制字符,你可以使用十六進制功能:

SELECT HEX('a') 
61 
+0

這是恥辱:(我試圖將此reqexp移植到MySQL http://www.w3.org/International/questions/qa-forms-utf-8.en.php – 2010-02-04 12:53:40

2

洛爾......基於以上你只能使用打印字符。這對我有效。我想讓它不匹配美國鍵盤上的字符和下面的表達式工作於MySQL 5.1中:

[^ -~] 

,將做同樣的事情

[^\x20-\x7E] 
+0

+1好點!另一方面它可能會遇到棘手的問題,數字超過0x7E – 2011-01-11 18:21:01

+0

它可以處理我需要的所有東西。 ''''''''''''\tàóªáíñ·] +「' – Shorin 2011-03-16 19:30:18

+1

hm ...我忘記了是否其中任何一個都高於0x7E ... – Shorin 2011-03-21 13:55:16

3

寫一個正則表達式就像在MySQL [\x61-\x65] ,你可以在一個concat中使用十六進制值:

SELECT CONVERT('a' USING BINARY) REGEXP CONCAT('[', 0x61, '-', 0x65, ']') 
相關問題