如何从字符串中删除重音字符? 特别是在IE6中,我有这样的东西:

accentsTidy = function(s){
    var r=s.toLowerCase();
    r = r.replace(new RegExp(/\s/g),"");
    r = r.replace(new RegExp(/[àáâãäå]/g),"a");
    r = r.replace(new RegExp(/æ/g),"ae");
    r = r.replace(new RegExp(/ç/g),"c");
    r = r.replace(new RegExp(/[èéêë]/g),"e");
    r = r.replace(new RegExp(/[ìíîï]/g),"i");
    r = r.replace(new RegExp(/ñ/g),"n");                
    r = r.replace(new RegExp(/[òóôõö]/g),"o");
    r = r.replace(new RegExp(/œ/g),"oe");
    r = r.replace(new RegExp(/[ùúûü]/g),"u");
    r = r.replace(new RegExp(/[ýÿ]/g),"y");
    r = r.replace(new RegExp(/\W/g),"");
    return r;
};

但是IE6让我很烦,它好像不喜欢我的正则表达式。


当前回答

假设你知道你在做什么,我怀疑IE6没有正确地解释文件的编码,因此不能识别文件中的非ascii字符:

确保文件保存为UTF-8格式(例如) 使用Fiddler或其他工具检查web服务器是否发送正确的内容编码HTTP报头。

(虽然它“闻起来”不对,但我会考虑做排序,比如在服务器上使用一些locale感知的东西……但无论如何…)

其他回答

假设你知道你在做什么,我怀疑IE6没有正确地解释文件的编码,因此不能识别文件中的非ascii字符:

确保文件保存为UTF-8格式(例如) 使用Fiddler或其他工具检查web服务器是否发送正确的内容编码HTTP报头。

(虽然它“闻起来”不对,但我会考虑做排序,比如在服务器上使用一些locale感知的东西……但无论如何…)

通过给定的测试,一个解决方案似乎要快得多:http://jsperf.com/diacritics/9

function removeDiacritics(str) {
   return str.replace(/[^A-Za-z0-9\s]+/g, function(a){
      return diacriticsMap[a] || a; 
   });
}
removeDiacritics(teste);

工作示例:http://jsbin.com/sovorute/1/edit

推理:这样做速度更快的一个原因是,我们只遍历由负正则表达式模式选择的特殊字符。最快的测试(不带in的字符串迭代)在给定文本上迭代1001,这意味着每个字符。这个函数只迭代了35次,输出了相同的结果。请记住,这将只替换地图中所指示的内容。

关于这个主题的经典文章:http://alistapart.com/article/accent-folding-for-auto-complete

来源:http://semplicewebsites.com/removing-accents-javascript,也提供了一个不错的人物地图。

从te reo Māori语言中移除宏子 给那些来这里想从马āori语中去掉宏子的人。 注意:当我格式化代码时,Stackblitz删除了map键上的单引号-他们必须确信这是OK的。这个代码的子集,谢谢

'use strict'; var macronMap = { ā: 'a', ē: 'e', ī: 'i', ō: 'o', ū: 'u', Ā: 'A', Ē: 'E', Ī: 'I', Ō: 'O', Ū: 'U', }; function deMacron(str) { return str.replace(/[^A-Za-z0-9\[\] ]/g, function (char) { return macronMap[char] || char; }); } function macronFree(str) { return str === deMacron(str); } console.assert( 'a, e, i, o, u, A, E, I, O, U' === deMacron('ā, ē, ī, ō, ū, Ā, Ē, Ī, Ō, Ū') ); console.assert(macronFree('a, e, i, o, u, A, E, I, O, U')); console.assert(!macronFree('ā, ē, ī, ō, ū, Ā, Ē, Ī, Ō, Ū')); document.body.append(deMacron('ā, ē, ī, ō, ū, Ā, Ē, Ī, Ō, Ū'));

我使用了string.js的latinise()方法,它可以让你这样做:

var output = S(input).latinise().toString();

使用ES2015/ES6 String.prototype.normalize(),

const str = "Crème Brulée"
str.normalize("NFD").replace(/[\u0300-\u036f]/g, "")
> "Creme Brulee"

注意:如果你想让\uFB01(fi)标准化(到fi),请使用NFKD。

这里发生了两件事:

Unicode标准格式将组合的字形分解为简单字形的组合。Crème的è最后表示为e + +。 使用正则表达式字符类来匹配U+0300→U+036F范围,现在可以很容易地全局消除变音符,Unicode标准将其方便地分组为组合变音符标记Unicode块。

从2021年开始,还可以使用Unicode属性转义:

str.normalize("NFD").replace(/\p{Diacritic}/gu, "")

有关性能测试,请参阅注释。

或者,如果你只是想排序

Intl。Collator有足够的支持~95%现在,polyfill也可以在这里,但我还没有测试它。

const c = new Intl.Collator();
["creme brulee", "crème brulée", "crame brulai", "crome brouillé",
"creme brulay", "creme brulfé", "creme bruléa"].sort(c.compare)
["crame brulai", "creme brulay", "creme bruléa", "creme brulee",
"crème brulée", "creme brulfé", "crome brouillé"]


["creme brulee", "crème brulée", "crame brulai", "crome brouillé"].sort((a,b) => a>b)
["crame brulai", "creme brulee", "crome brouillé", "crème brulée"]