MySQL将拉丁字符拉平为非拉丁字符

问题描述:

我正在寻找一个MySQL函数来将每个特殊的拉丁字符(不要与latin1字符集 - 我正在使用utf8)混淆到它的非拉丁等价物标准A-Z字母范围。MySQL将拉丁字符拉平为非拉丁字符

这里就是我简直想实现:

'Zażółć gęślą jaźń' --> 'Zazolc gesla jazn' 

我已经尝试了很多不同的特技CONVERTCAST功能。目前为止没有成功。

我也一派非常深刻,遗憾的是与MySQL每一个问题涉及到字符转换指的是不是我要找的典型latin1 default collation


我这里不远的目标是产品名称转换为上飞URI友好字符串,通过TRIGGER ... AFTER INSERT,例如

Crème Brûlée --> creme_brulee 

这些转换后的名称不仅可以用作SEO URI,还可以用作对缩略图文件名称的引用。

除了LOWER(@str)REPLACE(@str, ' ', '_'),其中一个步骤是将弄平这些拉丁字符。

我宁愿将这些转换后的名称保留在数据库中,但是从架构的角度来看,也许你知道一些更正确的方法?

+0

如果他们已经加入标准化的功能到MySQL,他们最有可能被用于这一点,因为他们可以将人物分成基本形式和diactirics。在过滤之后,变音符号将非常简单。不幸的是它还没有实现。 –

+0

@SamiKuhmonen谢谢,至少知道这一点。 – matewka

那么,Sami Kuhmonen对我的问题的评论实际上已经耗尽了所有可能性。

但我不得不去与任何工作解决方案,所以我决定PHP Doctrine'sDoctrine_Inflector:unaccent方法从GitHub复制。 MySQL实现definetely看起来不帅,但我猜嵌套REPLACE()功能是执行多字符串替换MySQL的唯一方法。

这里是整个TRIGGER

CREATE DEFINER = CURRENT_USER TRIGGER `product_BEFORE_INSERT` BEFORE INSERT ON `product` FOR EACH ROW 

# new value 
SET NEW.name_uri = LOWER(

REPLACE( 

# ugly set of nested replaces 
REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(

# the original value 
NEW.name, 

# every accented latin character represented by its ASCII code 
# is replaced with normalized letter 
CHAR(195,128), 'A'), CHAR(195,129), 'A'), CHAR(195,130), 'A'), CHAR(195,131), 'A'), CHAR(195,132), 'A'), CHAR(195,133), 'A'), 
CHAR(195,135), 'C'), CHAR(195,136), 'E'), CHAR(195,137), 'E'), CHAR(195,138), 'E'), CHAR(195,139), 'E'), CHAR(195,140), 'I'), 
CHAR(195,141), 'I'), CHAR(195,142), 'I'), CHAR(195,143), 'I'), CHAR(195,145), 'N'), CHAR(195,146), 'O'), CHAR(195,147), 'O'), 
CHAR(195,148), 'O'), CHAR(195,149), 'O'), CHAR(195,150), 'O'), CHAR(195,153), 'U'), CHAR(195,154), 'U'), CHAR(195,155), 'U'), 
CHAR(195,156), 'U'), CHAR(195,157), 'Y'), CHAR(195,159), 's'), CHAR(195,160), 'a'), CHAR(195,161), 'a'), CHAR(195,162), 'a'), 
CHAR(195,163), 'a'), CHAR(195,164), 'a'), CHAR(195,165), 'a'), CHAR(195,167), 'c'), CHAR(195,168), 'e'), CHAR(195,169), 'e'), 
CHAR(195,170), 'e'), CHAR(195,171), 'e'), CHAR(195,172), 'i'), CHAR(195,173), 'i'), CHAR(195,174), 'i'), CHAR(195,175), 'i'), 
CHAR(195,177), 'n'), CHAR(195,178), 'o'), CHAR(195,179), 'o'), CHAR(195,180), 'o'), CHAR(195,181), 'o'), CHAR(195,182), 'o'), 
CHAR(195,182), 'o'), CHAR(195,185), 'u'), CHAR(195,186), 'u'), CHAR(195,187), 'u'), CHAR(195,188), 'u'), CHAR(195,189), 'y'), 
CHAR(195,191), 'y'), 
# Decompositions for Latin Extended-A 
CHAR(196,128), 'A'), CHAR(196,129), 'a'), CHAR(196,130), 'A'), CHAR(196,131), 'a'), CHAR(196,132), 'A'), CHAR(196,133), 'a'), 
CHAR(196,134), 'C'), CHAR(196,135), 'c'), CHAR(196,136), 'C'), CHAR(196,137), 'c'), CHAR(196,138), 'C'), CHAR(196,139), 'c'), 
CHAR(196,140), 'C'), CHAR(196,141), 'c'), CHAR(196,142), 'D'), CHAR(196,143), 'd'), CHAR(196,144), 'D'), CHAR(196,145), 'd'), 
CHAR(196,146), 'E'), CHAR(196,147), 'e'), CHAR(196,148), 'E'), CHAR(196,149), 'e'), CHAR(196,150), 'E'), CHAR(196,151), 'e'), 
CHAR(196,152), 'E'), CHAR(196,153), 'e'), CHAR(196,154), 'E'), CHAR(196,155), 'e'), CHAR(196,156), 'G'), CHAR(196,157), 'g'), 
CHAR(196,158), 'G'), CHAR(196,159), 'g'), CHAR(196,160), 'G'), CHAR(196,161), 'g'), CHAR(196,162), 'G'), CHAR(196,163), 'g'), 
CHAR(196,164), 'H'), CHAR(196,165), 'h'), CHAR(196,166), 'H'), CHAR(196,167), 'h'), CHAR(196,168), 'I'), CHAR(196,169), 'i'), 
CHAR(196,170), 'I'), CHAR(196,171), 'i'), CHAR(196,172), 'I'), CHAR(196,173), 'i'), CHAR(196,174), 'I'), CHAR(196,175), 'i'), 
CHAR(196,176), 'I'), CHAR(196,177), 'i'), CHAR(196,178), 'IJ'), CHAR(196,179), 'ij'), CHAR(196,180), 'J'), CHAR(196,181), 'j'), 
CHAR(196,182), 'K'), CHAR(196,183), 'k'), CHAR(196,184), 'k'), CHAR(196,185), 'L'), CHAR(196,186), 'l'), CHAR(196,187), 'L'), 
CHAR(196,188), 'l'), CHAR(196,189), 'L'), CHAR(196,190), 'l'), CHAR(196,191), 'L'), CHAR(197,128), 'l'), CHAR(197,129), 'L'), 
CHAR(197,130), 'l'), CHAR(197,131), 'N'), CHAR(197,132), 'n'), CHAR(197,133), 'N'), CHAR(197,134), 'n'), CHAR(197,135), 'N'), 
CHAR(197,136), 'n'), CHAR(197,137), 'N'), CHAR(197,138), 'n'), CHAR(197,139), 'N'), CHAR(197,140), 'O'), CHAR(197,141), 'o'), 
CHAR(197,142), 'O'), CHAR(197,143), 'o'), CHAR(197,144), 'O'), CHAR(197,145), 'o'), CHAR(197,146), 'OE'), CHAR(197,147), 'oe'), 
CHAR(197,148), 'R'), CHAR(197,149), 'r'), CHAR(197,150), 'R'), CHAR(197,151), 'r'), CHAR(197,152), 'R'), CHAR(197,153), 'r'), 
CHAR(197,154), 'S'), CHAR(197,155), 's'), CHAR(197,156), 'S'), CHAR(197,157), 's'), CHAR(197,158), 'S'), CHAR(197,159), 's'), 
CHAR(197,160), 'S'), CHAR(197,161), 's'), CHAR(197,162), 'T'), CHAR(197,163), 't'), CHAR(197,164), 'T'), CHAR(197,165), 't'), 
CHAR(197,166), 'T'), CHAR(197,167), 't'), CHAR(197,168), 'U'), CHAR(197,169), 'u'), CHAR(197,170), 'U'), CHAR(197,171), 'u'), 
CHAR(197,172), 'U'), CHAR(197,173), 'u'), CHAR(197,174), 'U'), CHAR(197,175), 'u'), CHAR(197,176), 'U'), CHAR(197,177), 'u'), 
CHAR(197,178), 'U'), CHAR(197,179), 'u'), CHAR(197,180), 'W'), CHAR(197,181), 'w'), CHAR(197,182), 'Y'), CHAR(197,183), 'y'), 
CHAR(197,184), 'Y'), CHAR(197,185), 'Z'), CHAR(197,186), 'z'), CHAR(197,187), 'Z'), CHAR(197,188), 'z'), CHAR(197,189), 'Z'), 
CHAR(197,190), 'z'), CHAR(197,191), 's'), 

# Euro Sign 
CHAR(226,130,172), 'E'), 
# GBP (Pound) Sign 
CHAR(194,163), ''), 
'Ä', 'Ae'), 'ä', 'ae'), 'Ü', 'Ue'), 'ü', 'ue'), 
'Ö', 'Oe'), 'ö', 'oe'), 'ß', 'ss'), 
# Norwegian characters 
'Å', 'Aa'), 'Æ', 'Ae'), 'Ø', 'O'), 'æ', 'a'), 'ø', 'o'), 'å', 'aa') 

, ' ', '_')); 
+0

它很生病'REPLACE' - 我投票的所有方法:D为什么不在代码端使用iconv?我不确定您的TRIGGER会覆盖** UTF-8中定义的所有**特殊字符。 –

+0

@保罗,谢谢你的关注。我不想使用任何类型的代码端解决方案,因为所有的数据库操作都是通过SQL直接执行的。我没有包含任何类型的CMS(还),并且大多数产品将在生产部署期间插入。谈到所有的字符覆盖面,该网站是波兰语,它是一种糖果,所以我只需要波兰字母和法国的一些典型的蛋糕名称。 – matewka