可以使 REPLACE() 不区分重音(é = e)吗?
Posted
技术标签:
【中文标题】可以使 REPLACE() 不区分重音(é = e)吗?【英文标题】:Can REPLACE() be made accent insensitive (é = e)? 【发布时间】:2013-07-05 11:15:51 【问题描述】:我有一个使用 UTF-8- default
排序规则的表。
我在此表中有一个名为 company
的列,其值为 Café Rouge
当我这样查询时:
select * from company where name ='Cafe Rouge'
它列出这家公司是因为它处理字符é =e
,但是当我使用替换命令时,它不会将é
视为e
。
所以,
select replace('Café Rouge','e','z')
给我'Café Rougz'
,即它不会用z
替换é
。
任何建议都会受到重视
【问题讨论】:
我不确定这种行为是否可以改变 -REPLACE()
可能正在进行二进制比较。简单地替换é
不是一种选择吗?
为什么需要替换'é'?您可能应该创建新列company_normalized
,在其中放置不带重音、修剪、标准化空格等的值,然后在有用的地方简单地使用标准化变体,否则使用真实的公司名称......
No :( 这不是一个选项,因为可能有更多这样的字符会导致问题。此外,我无法将表更改为二进制排序规则,因为我们目前在任何地方都使用不区分大小写并将其更改为二进制将意味着不同地方的变化。
This page 说REPLACE()
应该以这种方式工作,因此您必须推出自己的功能。 Note: The REPLACE() function, unlike all other functions, always ignores the collation of the string input and performs a case-sensitive comparison.
@DrH 如果有的话,那就是select replace(replace(name, 'è', 'e'), 'à', 'a') from company;
【参考方案1】:
我认为您可以做的一件好事是维护第二列,使这些字符串保持正常形式;例如,此列将包含“Cafe Rouge”而不是“Café Rouge”。您可以在查询中投影异常字符,然后使用普通格式列进行查询。
【讨论】:
【参考方案2】:试试
SELECT REPLACE(CONVERT(name USING ascii), 'e', 'z')
在替换之前将name
列转换为ASCII。
【讨论】:
我也想过这个,但是它会破坏数据,因此很可能没有用。想象一下Café Üntenbärger
-> 最终会变成Cafz Untenbarger
但是,如果您想使用不同版本的“名称”数据进行比较,您可以使用别名加载替换版本,以便原始“名称”也可用。如果你能更清楚地解释你的意图会很有帮助。
我明白你的意思,但你将如何在 mysql 中进行比较?我不认为这是可能的。 (你需要一种脚本语言来做到这一点。)【参考方案3】:
我认为你做不到。更安全的选择是简单地对这些特定字符进行替换。
【讨论】:
【参考方案4】:为什么不对café rouge 进行选择,然后在每个返回的结果中替换所需的列?
【讨论】:
【参考方案5】:您需要在 mySQL 之外执行此操作。
您可以按照@Christian 所示使用CONVERT()
规范化mySQL 中的字符串,但这会破坏存在的任何其他非ASCII 字符:
Bürgercafé Römer
会结束
Burgercafz Romer
来自其他字符集(如西里尔文或中文)的字符将被完全删除。
最好的办法是专门替换所有要替换的字符。
replace('Café Rouge','e','z')
replace('Café Rouge','é','z')
replace('Café Rouge','è','z')
要完全做你想做的事,你必须将每个字符串加载到像 php 这样的编程语言中。
在那里,您可以执行以下操作:
从数据库中加载字符串;确保它是 UTF-8
将字符串拆分成字符(注意多字节字符 - 使用mb_split()
)
遍历每个字符
使用iconv($character, "UTF-8", "ASCII//TRANSLIT");
规范化字符
如果规范化字符的结果为e
,您就知道需要在字符串中替换它。
将修改后的字符串写回数据库。
然而,对于看似很小的事情来说,这看起来会带来很多麻烦。你确定有必要吗?
【讨论】:
以上是关于可以使 REPLACE() 不区分重音(é = e)吗?的主要内容,如果未能解决你的问题,请参考以下文章
Python:替换重音符号(é 到 e)、删除 [^a-zA-Z\d\s] 和 lower() 的有效方法 [重复]