在JavaScript中替换字符串中的一系列字符的最佳方法是什么

在JavaScript中替换字符串中的一系列字符的最佳方法是什么,javascript,regex,Javascript,Regex,我正在努力提高一个函数的性能,该函数接受XML字符串并在返回字符串之前替换某些字符(编码)。函数会受到冲击,因此尽快运行非常重要。通常情况下,所有角色都不存在,因此我想特别针对这一点进行优化。正如您将在示例代码中看到的,要替换的字符串很短,而且相对较少。源字符串通常较短(例如10-20个字符),但可能较长(例如200个字符左右) 到目前为止,我已经确保了正则表达式是预编译的,并且我已经消除了会减慢操作速度的嵌套函数(此时部分毫秒很重要) var objXMLToString=new XMLToS

我正在努力提高一个函数的性能,该函数接受XML字符串并在返回字符串之前替换某些字符(编码)。函数会受到冲击,因此尽快运行非常重要。通常情况下,所有角色都不存在,因此我想特别针对这一点进行优化。正如您将在示例代码中看到的,要替换的字符串很短,而且相对较少。源字符串通常较短(例如10-20个字符),但可能较长(例如200个字符左右)

到目前为止,我已经确保了正则表达式是预编译的,并且我已经消除了会减慢操作速度的嵌套函数(此时部分毫秒很重要)

var objXMLToString=new XMLToStringClass();
函数XMLToStringClass(){
本测试仪=/\\34 |\\39 |\\62 |\\60 |\\13\\10 |\\09 |\\92 |&/;
此项。替换=[];
var self=这个;
函数init(){
var re=new regexReplacePair(/\\34/g,“”);
自我更换推送(re);
re=新的regexReplacePair(/\\39/g,“”);
自我更换推送(re);
re=新的regexReplacePair(/\\62/g,“>”);
自我更换推送(re);

re=new regexReplacePair(/\\60/g,“您可以使用哈希查找:

str.replace(
    /(\\34|\\39|\\62|\\60|\\13\\10|\\09|\\92|&amp)/g,
    function () {
        return {
            "\\34": "\"",
            "\\39": "'",
            //...
            "&amp": "&"
        }[arguments(1)];
    }
);
或者您坚持要扩展原型:

var hash = {
    "\\34": "\"",
    "\\39": "'",
    //...
    "&amp": "&"
};

String.prototype.XMLToString = function () {
    return this.replace(
        /(\\34|\\39|\\62|\\60|\\13\\10|\\09|\\92|&amp)/g,
        function () { return hash[arguments(1)]; }
    }
);
这可能更快(需要进行基准测试):


更新 您可以从哈希生成正则表达式:

var arr = [];

for (var r in hash) {
    arr.push(r);
}

var re = new RegExp("(" + arr.join("|") + ")", "g");
然后将其用作:

s = s.replace(re, function () { ... });

下面是我对重构代码的尝试

  • 使objXMLToString成为静态对象-不需要是可实例化的
  • 去掉了内部init()函数-改为使用数组文字
  • 已转换的带有数组文字的regexReplacePair对象
  • 将for循环转换为while循环(通常更快)
  • 单返回点
  • 作用域newString变量(现在它不再是全局变量)
这是密码

var objXMLToString = {
     tester: /\\34|\\39|\\62|\\60|\\13\\10|\\09|\\92|&amp/
    ,replacements: [
         [/\\34/g,'"']
        ,[/\\39/g,"'"]
        ,[/\\62/g,">"]
        ,[/\\60/g,"<"]
        ,[/\\13\\10/g,"\n"]
        ,[/\\09/g,"\t"]
        ,[/\\92/g,"\\"]
        ,[/\&amp;/g,"&"]
    ]
}

String.prototype.XMLToString = function()
{
        var newString = this;
        if ( objXMLToString.tester.test( this ) )
        {
                var x = 0, replacer;
                while ( replacer = objXMLToString.replacements[x++] )
                {
                        newString = newString.replace( replacer[0], replacer[1] );
                }
        }
        return newString;
}
var objXMLToString={
测试仪:/\\34 |\\39 |\\62 |\\60 |\\13\\10 |\\09 |\\92 |和/
,替换:[
[/\\34/g,“'”
,[/\\39/g,“'”]
,[/\\62/g,“>”]

,[/\\60/g,“我已经对您的原始版本、Ates Gorals哈希、我的改进哈希、使用switch的版本和简单解决方案进行了基准测试。获胜者?简单解决方案

具有匹配数据(由85个字符组成的字符串)

使用不匹配的数据(85个字符的字符串):

(在我的Windows xp笔记本电脑上测试,1.7GHz,ymmv)

简单的解决方案是:

function XMLToString(str) {
    return (str.indexOf("\\")<0 && str.indexOf("&")<0) ? str :
    str
    .replace(/\\34/g,'"')
    .replace(/\\39/g,"'")
    .replace(/\\62/g,">")
    .replace(/\\60/g,"<")
    .replace(/\\13\\10/g,"\n")
    .replace(/\\09/g,"\t")
    .replace(/\\92/g,"\\")
    .replace(/\&amp;/g,"&");               
}

函数XMLToString_S1(str){

返回值(str.indexOf(“%”)优雅的解决方案-我忘记了较新版本的javascript允许您使用函数来确定替换值。优雅的解决方案,不幸的是它比原始版本慢。太棒了!我很惊讶——我的理解是编译正则表达式可能会很贵,在最终的解决方案中,每次调用函数.Comp时都会发生这种情况iling regexpes很昂贵,但浏览器会缓存它。啊,我明白了。我几乎想在它们前面用“\”来编码&'s,以消除第二次通过!这是一个好主意。如果你可以更改编码,有一种更快的方法。我更新了我的答案。
var objXMLToString = {
     tester: /\\34|\\39|\\62|\\60|\\13\\10|\\09|\\92|&amp/
    ,replacements: [
         [/\\34/g,'"']
        ,[/\\39/g,"'"]
        ,[/\\62/g,">"]
        ,[/\\60/g,"<"]
        ,[/\\13\\10/g,"\n"]
        ,[/\\09/g,"\t"]
        ,[/\\92/g,"\\"]
        ,[/\&amp;/g,"&"]
    ]
}

String.prototype.XMLToString = function()
{
        var newString = this;
        if ( objXMLToString.tester.test( this ) )
        {
                var x = 0, replacer;
                while ( replacer = objXMLToString.replacements[x++] )
                {
                        newString = newString.replace( replacer[0], replacer[1] );
                }
        }
        return newString;
}
        original  simple  hash  switch  ag-hash
FF3          194     188   250     240     424
IE7          188     172   641     906    2203
Chrome1      161     156   165     165     225
Opera9       640     625   531     515     734
        original  simple  hash  switch  ag-hash
FF3           39       4    34      34      39
IE7          125      15   125     125     156
Chrome1       45       2    54      54      57
Opera9       156      15   156     156     156
function XMLToString(str) {
    return (str.indexOf("\\")<0 && str.indexOf("&")<0) ? str :
    str
    .replace(/\\34/g,'"')
    .replace(/\\39/g,"'")
    .replace(/\\62/g,">")
    .replace(/\\60/g,"<")
    .replace(/\\13\\10/g,"\n")
    .replace(/\\09/g,"\t")
    .replace(/\\92/g,"\\")
    .replace(/\&amp;/g,"&");               
}
          matching    non match
FF3          44           3
IE7          93          16
Chrome1     132           1
Opera9      109          16
function XMLToString_S1(str) {
    return (str.indexOf("%")<0) ? str : decodeURIComponent(str).replace(/\x0D\x0A/g,"\n")
}