replace() with RegExp on array elements

2019-03-04 05:14发布

问题:

I want to write a JavaScript function which converts some simple BBcode Tags like [red] [/red] to Html-Tags. I think the replace() function is the best way to do it. I wrote a simple testfunction to try it, but it does not seem to work.

/**
* @function
* @description Replaces the bb-tags with html-tags
*/
function bbToHtml(form) {
    debugger

    var text = form.text.value;
    bbTags = new Array("[red]", "[yellow]", "[green]", "[/red]", "[/yellow]", "[/green]");
    htmlTags = new Array("<font color='red'>", "<font color='yellow'>", "<font color='green'>", "</font>", "<font>", "</font>");

    for (var i = 0; i < bbTags.length; i++) {
        var re = new RegExp(bbTags[i], "g");
        text = text.replace(re, htmlTags[i]);
    }

    alert(text);
}

It should convert "[red]hello[/red]" to "<font color='red'>hello</font>", but it just gives me a weird string.

What is wrong? I think this has something to do with my regular expression.

回答1:

[ and ] have special meaning in regular expressions and need to be escaped, moreover you do not need regular expressions the way you've written your code and can just do:

function bbToHtml(form) {
    debugger

    var text = form.text.value;
    bbTags = new Array("[red]", "[yellow]", "[green]", "[/red]", "[/yellow]", "[/green]");
    htmlTags = new Array("<font color='red'>", "<font color='yellow'>", "<font color='green'>", "</font>", "<font>", "</font>");

    for (var i = 0; i < bbTags.length; i++) {
        while(text.indexOf(bbTags[i])!==-1){
            text = text.replace(bbTags[i], htmlTags[i]);
        }
    }

    alert(text);
}

Just to let you know, you can use array literals so instead of arrays. new Array(comma seperated values) is identical to [comma seperated values] in javascript. Also, you can use your array like a map in your case, for example:

var bbTagsToHTML = {}
bbTagsToHtml["[red]"] = "<font color='red'>"

and iterate through that.

If you would like you can escape your regular expressions too, please see How do you use a variable in a regular expression? for a function that does that.

You can also do that manually. "[red]" becomes "\[red\]" (the bracket escaped).



回答2:

just change this line

text = text.replace(re, htmlTags[i]);

into

text = text.replace(bbTags[i], htmlTags[i]);

removing unuseful code.

replace works also on 'normal' (not regex) values as argument.



回答3:

If you want to do it with regex you can simplify a lot. No arrays or loops:

var str = '[red]foo[/red] hello world [blue]hey[/blue]',
    re = /\[(\w+)\](.*)\[\/\1\]/g;

str = str.replace(re, '<font color="$1">$2</font>');

console.log(str);
//^ <font color="red">foo</font> hello world <font color="blue">hey</font>

Also, as a side note, font is rarely used anymore I'd suggest you use a span with a class.