2010-02-04 3 views
4

J'ai un comportement très étrange de mysql. La sélection ci-dessous RENDEMENTS 0:Caractères hexadécimaux dans regexp correspondant dans mysql

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

Cependant sémantiquement sélectionnez ci-dessous RENDEMENTS 1:

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

Savez-vous ce qui se passe ici? J'ai testé cela dans mysql 5.0.0.3031 et 4.1.22

J'ai besoin des caractères hexadécimaux pour créer une expression rationnelle qui correspond lorsqu'une chaîne binaire est encodée dans utf8. Une version perl de cette expression rationnelle peut être trouvée sur w3c site. Il semble comme suit:

$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

J'ai supprimé la balise 'utf-8' car cette question concerne purement la syntaxe de MySQL. Votre autre question est celle qui traite des aspects UTF-8: http://stackoverflow.com/questions/2199825/how-can-i-check-if-a-binary-string-is-utf-8-in -mysql –

Répondre

2

Cela correspond aussi:

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

La raison est que \x est comme x et alors interprété a vient entre 1 et x. Le reste de votre regex est juste des caractères ordinaires qui ne sont pas pertinents ici car ils sont déjà dans la gamme [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. 

Je ne suis pas sûr de ce que vous essayez d'atteindre, mais si vous voulez des caractères hexadécimaux, vous pouvez utiliser la fonction hexagonale:

SELECT HEX('a') 
61 
+0

C'est dommage :(. J'ai essayé de porter ce reqexp à mysql http://www.w3.org/International/questions/qa-forms-utf-8.en.php –

2

Lol ... en fonction de ce qui précède, vous peut simplement utiliser les caractères d'impression. Cela a fonctionné pour moi. Je voulais le faire correspondre des caractères non sur un clavier Etats-Unis et l'expression suivante fonctionne sur MySQL 5.1:

[^ -~] 

Cela fera la même chose que

[^\x20-\x7E] 
+0

+1 bon point! d'autre part, il pourrait être difficile avec le numéro au-dessus de 0x7E –

+0

Il a travaillé avec prettymuch tout ce dont j'avais besoin. '... ET l.Description PAS RLIKE" [\ n "" '¿½-é ° ± ... • -â € ¾ '¢ ¼®ç²º \t àóªáíñ ·] + "' – Shorin

+1

hm ... J'oublie si l'un d'entre eux est au-dessus de 0x7E ... – Shorin

3

à écrire une expression rationnelle comme [\x61-\x65] dans mysql , vous pouvez utiliser des valeurs hexadécimales à l'intérieur d'une concaténation:

SELECT CONVERT('a' USING BINARY) REGEXP CONCAT('[', 0x61, '-', 0x65, ']') 
Questions connexes