javascript regex replace, how to provide regex con

2019-06-05 13:43发布

问题:

Using the JS replace function with regex, and will have dozens of replace statements.

var NewHTML = OriginalHTML
.replace(/\bJavaScript\b/gi, "<a href=\"http://js.com/\">$&</a>")
.replace(/\bMySQL\b/gi, "<a href=\"http://www.mysql.com/\">$&</a>")
;

To make it more readable and more manageable (i.e. easier to change the regex pattern or flags by changing it in one place instead of on every line), trying to pull the replace regex condition and replace flags out into a separate variable:

var pattern = /\b(?!\-)(?!\/)\b(?!\-)/gi;

var NewHTML = OriginalHTML
.replace("JavaScript", "<a href=\"http://js.com/\">$&</a>", pattern)
.replace("MySQL", "<a href=\"http://www.mysql.com/\">$&</a>", pattern)    

Problem is, the inline call is being completely ignored... both the regex portion and the flags portion.

Can anyone spot what's wrong with the JS replace call or declaration of the regex/flags variable? :-)

Thanks!

回答1:

I would use a lookup object to map the originals to URLs:

// Original string
var o = "MySql is a DBMS, whereas javascript is a client side scripting language";

//Patterns
var patterns = {
    "javascript": "http://js.com/",
    "mysql": "http://www.mysql.com/"
};

//Constructing regex
RegExp.escape= function(s) {
    return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')
};
var keys = [];
for (i in patterns) {
    if (patterns.hasOwnProperty(i)) {
        keys.push(RegExp.escape(i));
    }
}
var pattern = new RegExp("\\b(" + keys.join("|") + ")\\b", "gi");

//Replace
var n = o.replace(pattern, function(m, g1) {
    return "<a href='" + patterns[g1.toLowerCase()] + "'>" + g1 + "< /a>";
});
console.log(n);

Here is a demonstration: http://jsfiddle.net/qP9Er/


EDIT:

As per your request, here is a version that replaces the first n occurrences. You can find a demonstration here:

// Original string
var o = '<p>Test 1 (JavaScript - <strong>1st keyword instance to be replaced</strong>): <br><a href="http://js1.net">Link to JavaScript site (existing URL)</a> is a scripting language commonly implemented as part of a web browser in order to create enhanced user interfaces and dynamic websites. JavaScript is very flexible.</p><p>more text here... and another mention of JavaScript. also javascript and JAVAScrIPT <br><br></p><p>Test 2 (MySQL - <strong>1st keyword instance to be replaced</strong>): <br><a href="http://www.mysql.com">MySQL</a>  (existing URL) is the most popular open-source database system.</p> <p><a href="http://www.themysqllink.com">link to a MySQL site</a> (existing URL).</p><p> More stuff about Mysql, also mysql and mySQL</p>';

//Patterns
var patterns = {
    "javascript": "http://js.com/",
    "mysql": "http://www.mysql.com/",
    "mention": "http://www.x.com/"
};

//Number of replacements
var num = 1;

//Constructing regex
RegExp.escape = function(s) {
    return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
};
var keys = [];
for (key in patterns) {
    if (patterns.hasOwnProperty(key)) {
        keys.push(RegExp.escape(key));
    }
}
var regexen = [];
for (var i = 0; i < keys.length; i++) {
    regexen[i] = new RegExp("\\b(" + keys[i] + ")\\b(?![^<]*?<\/a>)", "i");
}

//Replace
for (var i = 0; i < regexen.length; i++) {
    var count = 0;
    var pattern = regexen[i];
    while (count < num) {
        o = o.replace(pattern, function(m, g1) {
            return "<a href='" + patterns[g1.toLowerCase()] + "'>" + g1 + "</a>";
        });
        count++;
    }
}
document.write(o);


回答2:

The .replace() function only takes 2 arguments.

You can build a regex dynamically by building it as a string and then passing it to the RegExp() constructor.



回答3:

The flags parameter is nonstandard. And more importantly, it only tags flags such as "gi" and not a whole regular expression.

I would write a loop to deal with the duplication. Or have a function create the String so I can keep it in once place.