如何从字符串中删除重音字符? 特别是在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让我很烦,它好像不喜欢我的正则表达式。


当前回答

这对我很有用。JavaScript,谷歌应用程序脚本,GAS

function normalizetext(text) {
  var weird = 'öüóőúéáàűíÖÜÓŐÚÉÁÀŰÍçÇ!@£$%^&*()_+?/*."';
var normalized = 'ouooueaauiOUOOUEAAUIcC                 ';
var idoff = -1,new_text = '';
var lentext = text.toString().length -1

for (i = 0; i <= lentext; i++) {
idoff = weird.search(text.charAt(i));
if (idoff == -1) {
new_text = new_text + text.charAt(i);
} else {
new_text = new_text + normalized.charAt(idoff);
}

}
return new_text;

}

其他回答

使用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"]

以上所有都不能与Mac OS上使用的分解字符一起工作。 为了在这种情况下删除变音符,它更简单:

r = r.replace(new RegExp(/[\u0300-\u036f]/g),"")

参见Olivier Miakinen的评论: https://groups.google.com/d/msg/fr.comp.lang.regexp/6IGJTbedGTM/G0sB2kAsR34J (法语张贴)

在NPM中有一个包:latinize

这是解决这个问题的一个很好的方案。

我发现所有这些都有点笨拙,而且我不太擅长正则表达式,所以这里有一个更简单的版本。将它翻译成你最喜欢的服务器端语言是很容易的,假设字符串已经在Unicode中:

// String containing replacement characters for stripping accents 
var stripstring = 
    'AAAAAAACEEEEIIII'+
    'DNOOOOO.OUUUUY..'+
    'aaaaaaaceeeeiiii'+
    'dnooooo.ouuuuy.y'+
    'AaAaAaCcCcCcCcDd'+
    'DdEeEeEeEeEeGgGg'+
    'GgGgHhHhIiIiIiIi'+
    'IiIiJjKkkLlLlLlL'+
    'lJlNnNnNnnNnOoOo'+
    'OoOoRrRrRrSsSsSs'+
    'SsTtTtTtUuUuUuUu'+
    'UuUuWwYyYZzZzZz.';

function stripaccents(str){
    var answer='';
    for(var i=0;i<str.length;i++){
        var ch=str[i];
        var chindex=ch.charCodeAt(0)-192;   // Index of character code in the strip string
        if(chindex>=0 && chindex<stripstring.length){
            // Character is within our table, so we can strip the accent...
            var outch=stripstring.charAt(chindex);
            // ...unless it was shown as a '.'
            if(outch!='.')ch=outch;
        }
        answer+=ch;
    }
    return answer;
}
$scope.legal_name = $sanitize($scope.legal_name);
    console.log("Name before function...",$scope.legal_name);

    var str = "";
    for(var i=0; i < $scope.legal_name.length; i++) {
        var charName = $scope.legal_name.charAt(i);
        if((charName == '&') && ($scope.legal_name.charAt(i + 1) == '#')){
            var count = 0;
            var subString = "";
            while(true) {
                if(($scope.legal_name.charCodeAt(i + 2 + count) > 47) && ($scope.legal_name.charCodeAt(i + 1 + count) < 58 )) {
                    subString = subString + $scope.legal_name.charAt(i + 2 + count);
                    count++;
                } else {
                    if(subString.length > 0) {
                        var value = parseInt(subString);
                        str = str + String.fromCharCode(value);
                        i = i + 1 + count; 
                        break;
                    }
                }
            }               
        } else {
            str = str + charName;
        }
    }
    $scope.legal_name = str;
    console.log("Name After function...",str);