web-dev-qa-db-ja.com

URLを検証するJavascript正規表現

次の正規表現でURLを検証しています。 google.comも検証したいのですが、falseを返します。 google.comを検証するために、以下のR.Eで変更できるもの。

console.log(learnRegExp('http://www.google-com.123')); // false
console.log(learnRegExp('https://www.google-com.com')); // true
console.log(learnRegExp('http://google-com.com')); // true
console.log(learnRegExp('http://google.com')); //true
console.log(learnRegExp('google.com')); //false

function learnRegExp(){
  return /^(ftp|https?):\/\/+(www\.)?[a-z0-9\-\.]{3,}\.[a-z]{3}$/.test(learnRegExp.arguments[0]);
}
18

これは一般的にURLを検証します

console.log('http://www.google-com.123.com', validateUrl('http://www.google-com.123.com')); // true 
console.log('http://www.google-com.123', validateUrl('http://www.google-com.123')); // false 
console.log('https://www.google-com.com', validateUrl('https://www.google-com.com')); // true 
console.log('http://google-com.com', validateUrl('http://google-com.com')); // true 
console.log('http://google.com', validateUrl('http://google.com')); //true 
console.log('google.com', validateUrl('google.com')); //false
console.log('http://www.gfh.', validateUrl('http://www.gfh.')); //false
console.log('http://www.gfh.c', validateUrl('http://www.gfh.c')); //false
console.log('http://www.gfh:800000', validateUrl('http://www.gfh:800000')); //false
console.log('www.google.com ', validateUrl('www.google.com ')); //false
console.log('http://google', validateUrl('http://google')); //false
console.log('//cdnblabla.cloudfront.net/css/app.css', validateUrl('//cdnblabla.cloudfront.net/css/app.css')); //true

function validateUrl(value) {
  return /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(value);
}

一致する必要があります

["//www.google.com", "//cdnblabla.cloudfront.net/css/app.css", "http://✪df.ws/123", "http://userid:[email protected]:8080", "http://userid:[email protected]:8080/", "http://[email protected]", "http://[email protected]/", "http://[email protected]:8080", "http://[email protected]:8080/", "http://userid:[email protected]", "http://userid:[email protected]/", "http://142.42.1.1/", "http://142.42.1.1:8080/", "http://➡.ws/䨹", "http://⌘.ws", "http://⌘.ws/", "http://foo.com/blah_(wikipedia)#cite-1", "http://foo.com/blah_(wikipedia)_blah#cite-1", "http://foo.com/unicode_(✪)_in_parens", "http://foo.com/(something)?after=parens", "http://☺.damowmow.com/", "http://code.google.com/events/#&product=browser", "http://j.mp", "ftp://foo.bar/baz", "http://foo.bar/?q=Test%20URL-encoded%20stuff", "http://مثال.إختبار", "http://例子.测试"].map(function(url) {
  console.log(url, validateUrl(url));
});

function validateUrl(value) {
  return /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(value);
}

失敗するはずです

["http://", "http://.", "http://..", "http://../", "http://?", "http://??", "http://??/", "http://#", "http://##", "http://##/", "http://foo.bar?q=Spaces should be encoded", "//", "//a", "///a", "///", "http:///a", "foo.com", "rdar://1234", "h://test", "http:// shouldfail.com", ":// should fail", "http://foo.bar/foo(bar)baz quux", "ftps://foo.bar/", "http://-error-.invalid/", "http://-a.b.co", "http://a.b-.co", "http://0.0.0.0", "http://10.1.1.0", "http://10.1.1.255", "http://224.1.1.1", "http://1.1.1.1.1", "http://123.123.123", "http://3628126748", "http://.www.foo.bar/", "http://www.foo.bar./", "http://.www.foo.bar./", "http://10.1.1.1", "http://10.1.1.254"].map(function(url) {
  console.log(url, validateUrl(url));
});

function validateUrl(value) {
  return /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(value);
}

仕組み

// protocol identifier
"(?:(?:(?:https?|ftp):)?//)"
// user:pass authentication
"(?:\\S+(?::\\S*)?@)?"
"(?:"
// IP address exclusion
// private & local networks
"(?!(?:10|127)(?:\\.\\d{1,3}){3})"
"(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})"
"(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})"
// IP address dotted notation octets
// excludes loopback network 0.0.0.0
// excludes reserved space >= 224.0.0.0
// excludes network & broacast addresses
// (first & last IP address of each class)
"(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])"
"(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}"
"(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))"
"|"
// Host name
"(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)"
// domain name
"(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*"
// TLD identifier
"(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))"
// port number
"(?::\\d{2,5})?"
// resource path
"(?:[/?#]\\S*)?"

これはすべてこれに由来します Gist 、これがすべてのニーズを満たすことを願っています

67
Christian David

これは私に最適です。私はそれが他の誰かに完璧であることを願っています! :)

/^((https?):\/\/)?([w|W]{3}\.)+[a-zA-Z0-9\-\.]{3,}\.[a-zA-Z]{2,}(\.[a-zA-Z]{2,})?$/

6
Rorshack

ここでは、「ftp/http(s)://」を必須にする必要はありません。使用する "?"このため。

function learnRegExp(){
  return /((ftp|https?):\/\/)?(www\.)?[a-z0-9\-\.]{3,}\.[a-z]{3}$/.test(learnRegExp.arguments[0]);
}
2
ArVan
/(http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/
0
Acn

^...記号は、で始まると言っているので、最終ログは意味があります。つまり、文字列はftpまたはhttp(s)で始まっていません。また、...$で、文字列が3文字で終わる必要があるということを言っています。これはまた失敗します(2行目)このように終了しません。いくつかのマイナーな調整とあなたがそこにいるはずです。

0
T I

各ケースに複数の正規表現がないのはなぜですか?

  1. 有効な英数字のURL:/^https?:\/\/([\w\d\-]+\.)+\w{2,}(\/.+)?$/

    _http://sub_do-main.a.co_のようなものに_https://a.a.a.a.aa/my-awesome_url?asd=12_で動作します。以下で試すことができます: https://regex101.com/r/oXFuGy/2

  2. IPv4、短くて高速ですが、100%正確ではありません(validator.jsで使用されます):/^(\d{1,3}(\.|$)){4}/。 _999.999.999.999._のようなものを許可します

  3. IPv4、より大きく、より遅いが、100%正確:^(((25[0-5])|(2[0-4]\d)|(1\d{2})|(\d{1,2}))\.){3}(((25[0-5])|(2[0-4]\d)|(1\d{2})|(\d{1,2})))$。ここで見つけました: https://stackoverflow.com/a/50650510/2862917
  4. IPv6(これが最善/正確/高速のアプローチであるかどうか正確にはわかりません:^(([\da-fA-F]{0,4}:){1,7}[\da-fA-F]{0,4})$。ここで見つけられます: 有効なIPv6アドレスに一致する正規表現 IP(少なくともそれらのv6)の検証を試みるために正規表現の使用を停止する方が良い理由に答えてください。
0