问题
I'm writing a chrome extension which allows the user to modify content on specific websites. I'd like the user to be able to specify these websites using wildcards, for example http://*.google.com
or http://google.com/*
I found the following code
currentUrl = "http://google.com/";
matchUrl = "http://*.google.com/*";
match = RegExp(matchUrl.replace(/\*/g, "[^]*")).test(currentUrl);
But there are a few problems with it.
http://test.google.com/
is a match
http://google.com/
is not a match
http://test.google.com
is not a match
http://.google.com/
is a match
Clarification:
http://google.com
Isn't a match, and that is the real problem.
So how can I can I create a JavaScript code snippet that will check if there is a match correctly?
回答1:
I suggest parsing the URL into protocol, base part and the rest, and then re-build the validation regex replacing *
inside the base part with (?:[^/]*\\.)*
and otherwise with (?:/[^]*)?
. Also, you must escape all other special chars with .replace(/[?()[\]\\.+^$|]/g, "\\$&")
. You will also need anchors (^
for start of string and $
for the end of string position) to match the entire string. A case insensitive /i
modifier is just a bonus to make the pattern case insensitive.
So, for this exact matchUrl
, the regex will look like
/^http:\/\/(?:[^\/]*\.)*google\.com(?:\/[^]*)?$/
See the regex demo
var rxUrlSplit = /((?:http|ftp)s?):\/\/([^\/]+)(\/.*)?/;
var strs = ['http://test.google.com/', 'http://google.com/','http://test.google.com', 'http://.google.com/','http://one.more.test.google.com'];
var matchUrl = "http://*.google.com/*";
var prepUrl = "";
if ((m=matchUrl.match(rxUrlSplit)) !== null) {
prepUrl = m[1]+"://"+m[2].replace(/[?()[\]\\.+^$|]/g, "\\$&").replace(/\*\\./g,'(?:[^/]*\\.)*').replace(/\*$/,'[^/]*');
if (m[3]) {
prepUrl+= m[3].replace(/[?()[\]\\.+^$|]/g, "\\$&").replace(/\/\*(?=$|\/)/g, '(?:/[^]*)?');
}
}
if (prepUrl) {
// console.log(prepUrl); // ^http://(?:[^/]*\.)*google\.com(?:/[^]*)?$
var rx = RegExp("^" + prepUrl + "$", "i");
for (var s of strs) {
if (s.match(rx)) {
console.log(s + " matches!<br/>");
} else {
console.log(s + " does not match!<br/>");
}
}
}
回答2:
with this matchUrl
matchUrl = "http://*.google.com/*";
the RexExp is something like this
"http://.*.google.com/.*"
so try to replace the * entered by the user with .* in the regexp match
you can use this tool to test it
来源:https://stackoverflow.com/questions/39094017/javascript-match-url-with-wildcards-chrome-extension