What is the best way to replace a series of characters in a string in JavaScript

I am working on improving the performance of a function that takes an XML string and replaces some characters (encoding) before returning the string. The function clogs, so it’s important to work as quickly as possible. The case of USUAL is that none of the characters are present, so I would especially like to optimize for this. As you will see in the code example, the lines that need to be replaced are short and relatively small. Source strings are often short (for example, 10-20 characters), but can be longer (for example, 200 characters or so).

So far, I have guaranteed that regular expressions are precompiled, and I excluded nested functions that slowed down (partial milliseconds matter at the moment.)

var objXMLToString = new XMLToStringClass();
function XMLToStringClass(){
    this.tester= /\\34|\\39|\\62|\\60|\\13\\10|\\09|\\92|&amp/;
    this.replacements=[];
    var self=this;
    function init(){        
        var re = new regexReplacePair(/\\34/g,'"');
        self.replacements.push(re);
        re = new regexReplacePair(/\\39/g,"'");
        self.replacements.push(re);
        re = new regexReplacePair(/\\62/g,">");
        self.replacements.push(re);
        re = new regexReplacePair(/\\60/g,"<");
        self.replacements.push(re);
        re = new regexReplacePair(/\\13\\10/g,"\n");
        self.replacements.push(re);
        re = new regexReplacePair(/\\09/g,"\t");
        self.replacements.push(re);
        re = new regexReplacePair(/\\92/g,"\\");
        self.replacements.push(re);
        re = new regexReplacePair(/\&amp;/g,"&");       
        self.replacements.push(re);     
    }
    init();
}


function regexReplacePair(regex,replacementString){
    this.regex = regex;
    this.replacement = replacementString;
}

String.prototype.XMLToString = function() {
        newString=this;
        if(objXMLToString.tester.test(this)){
            for (var x = 0;x<objXMLToString.replacements.length;x++){
                newString=newString.replace(objXMLToString.replacements[x].regex,objXMLToString.replacements[x].replacement);
            }
            return newString;
        }
        return this;
}
  • Is it possible that the String.replacefunctions will be better in this scenario ?
  • I am currently replacing all characters, if there is one character match - is it possible that testing, and then conditionally replacing it, would be better? If so, could it indexOfbe faster than a regular expression for this dataset?
+5
source share
3 answers

I compared your original version, the Ates Horals hash, the improved hash, the switch version and the simple solution. Winner? A simple solution!

( 85 )

        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

( 85 ):

        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

( xp, 1,7 , 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,"&");               
}

:

, ( indexOf ). , , . . , , .

, , . , regexp . .

Ates Horals, ( ), , , .

UPDATE 1 Bugfix: .

2

, , , , .

"\ dd", dd - , "% xx", xx - . decodeURIComponent, , , unicode.

          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")
}

, "\ 09test\60\34string\34\62\13\10 \" "% 09test% 3c% 22string% 22% 3e% 0d% 0a".

+6

-:

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)]; }
    }
);

( ):

String.prototype.XMLToString = function () {
    var s = this;

    for (var r in hash) {
        s = s.split(r).join(hash[r]);
    }

    return s;
);

Update

:

var arr = [];

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

var re = new RegExp("(" + arr.join("|") + ")", "g");

:

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

  • objXMLToString -
  • init() -
  • regexReplacePair
  • 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;
}
+2

All Articles