正则表达式来匹配网址

我正在使用下面的正则表达式来匹配一个URL:

$search = "/([\S]+\.(MUSEUM|TRAVEL|AERO|ARPA|ASIA|COOP|INFO|NAME|BIZ|CAT|COM|INT|JOBS|NET|ORG|PRO|TEL|AC|AD|AE|AF|AG|AI|AL|AM|AN|AO|AQ|AR|AS|AT|AU|au|AW|AX|AZ|BA|BB|BD|BE|BF|BG|BH|BI|BJ|BL|BM|BN|BO|BR|BS|BT|BV|BW|BY|BZ|CA|CC|CD|CF|CG|CH|CI|CK|CL|CM|CN|CO|CR|CU|CV|CX|CY|CZ|DE|DJ|DK|DM|DO|DZ|EC|EDU|EE|EG|EH|ER|ES|ET|EU|FI|FJ|FK|FM|FO|FR|GA|GB|GD|GE|GF|GG|GH|GI|GL|GM|GN|GOV|GP|GQ|GR|GS|GT|GU|GW|GY|HK|HM|HN|HR|HT|HU|ID|IE|IL|IM|IN|IO|IQ|IR|IS|IT|JE|JM|JO|JP|KE|KG|KH|KI|KM|KN|KP|KR|KW|KY|KZ|LA|LB|LC|LI|LK|LR|LS|LT|LU|LV|LY|MA|MC|MD|ME|MF|MG|MH|MIL|MK|ML|MM|MN|MO|MOBI|MP|MQ|MR|MS|MT|MU|MV|MW|MX|MY|MZ|NA|NC|NE|NF|NG|NI|NL|NO|NP|NR|NU|NZ|OM|PA|PE|PF|PG|PH|PK|PL|PM|PN|PR|PS|PT|PW|PY|QA|RE|RO|RS|RU|RW|SA|SB|SC|SD|SE|SG|SH|SI|SJ|SK|SL|SM|SN|SO|SR|ST|SU|SV|SY|SZ|TC|TD|TF|TG|TH|TJ|TK|TL|TM|TN|TO|R|H|TP|TR|TT|TV|TW|TZ|UA|UG|UK|UM|US|UY|UZ|VA|VC|VE|VG|VI|VN|VU|WF|WS|YE|YT|YU|ZA|ZM|ZW)([\S]*))/i"; 

但它有点搞砸了,因为它也匹配我不想要的“abc.php”。 和一些像ABC …测试。 我希望它匹配abc.com虽然。 和www.abc.com以及http://abc.com 。

这只是需要稍微调整,但我不知道是什么。 (应该有一个斜线后的任何域名,它现在没有检查,它只是检查\ S)

感谢您的时间。

 $search = "#^((?# the scheme: )(?:https?://)(?# second level domains and beyond: )(?:[\S]+\.)+((?# top level domains: )MUSEUM|TRAVEL|AERO|ARPA|ASIA|EDU|GOV|MIL|MOBI|(?# )COOP|INFO|NAME|BIZ|CAT|COM|INT|JOBS|NET|ORG|PRO|TEL|(?# )A[CDEFGILMNOQRSTUWXZ]|B[ABDEFGHIJLMNORSTVWYZ]|(?# )C[ACDFGHIKLMNORUVXYZ]|D[EJKMOZ]|(?# )E[CEGHRSTU]|F[IJKMOR]|G[ABDEFGHILMNPQRSTUWY]|(?# )H[KMNRTU]|I[DELMNOQRST]|J[EMOP]|(?# )K[EGHIMNPRWYZ]|L[ABCIKRSTUVY]|M[ACDEFGHKLMNOPQRSTUVWXYZ]|(?# )N[ACEFGILOPRUZ]|OM|P[AEFGHKLMNRSTWY]|QA|R[EOSUW]|(?# )S[ABCDEGHIJKLMNORTUVYZ]|T[CDFGHJKLMNOPRTVWZ]|(?# )U[AGKMSYZ]|V[ACEGINU]|W[FS]|Y[ETU]|Z[AMW])(?# the path, can be there or not: )(/[a-z0-9\._/~%\-\+&\#\?!=\(\)@]*)?)$#i"; 

刚刚清理了一下。 这将匹配HTTP(s)地址,并且只要您从IANA正确复制了所有顶级域名,只有那些标准化( 不会http://localhost匹配)并且 http://声明相同的域名。

最后,你应该以路径部分结束,如果它在那里,它总是以/开始。

不过,我建议按照大脑:如果你不确定这一点,以更温和的方式学习正则表达式,并使用已证明的模式来处理复杂的任务。

干杯,

顺便说一下:你的正则表达式也会匹配something.rsomething.h (在你的例子中的| TO |和| TR |之间)。 我把它们放在我的版本中,因为我猜这是一个错字。

重读这个问题:改变

  )(?:https?://)(?# 

  )(?:https?://)?(?# 

(有一个额外的)来匹配没有该方案的“网址”。

不是OP所要求的,但是这是一个简单得多的正则表达式,每当IANA引入新的顶级域名(TLD)时就不需要更新。 我相信这对于大多数简单的需求来说已经足够了:

 ^(?:https?://)?(?:[\w]+\.)(?:\.?[\w]{2,})+$ 

没有TLD列表,localhost不匹配,子部分的数量必须> = 2,每个子部分的长度必须> = 2(fx:“aa”不匹配,但“a.ab”匹配)。

这个问题出人意料地很难找到答案。 我发现的正则表达式太复杂了,而且正则表达式太过于复杂,难以实现。

最后想出了:

 /(\S+\.(com|net|org|edu|gov)(\/\S+)?)/ 

适用于http://example.com https://example.com http://example.com/foo

说明:

  • 寻找.com等
  • 匹配之前的一切,直到空间
  • 匹配它后面的所有内容

这将得到任何网址的整体,包括?=和#/如果它们存在:

/[A-Za-z]+://[A-Za-z0-9-_]+.[A-Za-z0-9-_:%&;\?#/.=]+/g

使用单个正则表达式来匹配URL字符串使代码难以理解。 我建议使用parse_url将URL拆分成其组件(这不是一个简单的任务),并检查每个部分与正则表达式。

更改正则表达式的结尾(/\S*)?)$应该解决您的问题。

解释一下在做什么 –

  • 它正在寻找/后面跟着一些字符(而不是空格)
  • 这场比赛是可选的? 指示0或1次
  • 最后它应该跟着一个字符串的结尾(或者将它改为\b以匹配一个字的边界)。

$:美元表示字符串的结尾。
例如\ d * $将匹配以数字结尾的字符串。 所以你需要添加$!

正则表达式匹配所有的网址(无www,没有www,http或https,没有http或https,包括所有2-6字母顶级域名[国家,ex'ly','us'],端口,查询字符串,并锚定['#'])。 这不是100%,但比我在网上发布的任何东西都要好。

它使用来自第一个答案的顶级域名,以及在我的搜索中找到的其他技术。 它将返回任何有效的URL,这是\ b进入的地方。 由于尾部的'/'也由\ b触发,最后一个匹配一个或多个'?'。

 /\b((http(s?):\/\/)?([a-z0-9\-]+\.)+(MUSEUM|TRAVEL|AERO|ARPA|ASIA|EDU|GOV|MIL|MOBI|COOP|INFO|NAME|BIZ|CAT|COM|INT|JOBS|NET|ORG|PRO|TEL|A[CDEFGILMNOQRSTUWXZ]|B[ABDEFGHIJLMNORSTVWYZ]|C[ACDFGHIKLMNORUVXYZ]|D[EJKMOZ]|E[CEGHRSTU]|F[IJKMOR]|G[ABDEFGHILMNPQRSTUWY]|H[KMNRTU]|I[DELMNOQRST]|J[EMOP]|K[EGHIMNPRWYZ]|L[ABCIKRSTUVY]|M[ACDEFGHKLMNOPQRSTUVWXYZ]|N[ACEFGILOPRUZ]|OM|P[AEFGHKLMNRSTWY]|QA|R[EOSUW]|S[ABCDEGHIJKLMNORTUVYZ]|T[CDFGHJKLMNOPRTVWZ]|U[AGKMSYZ]|V[ACEGINU]|W[FS]|Y[ETU]|Z[AMW])(:[0-9]{1,5})?((\/([a-z0-9_\-\.~]*)*)?((\/)?\?[a-z0-9+_\-\.%=&]*)?)?(#[a-zA-Z0-9!$&'()*+.=-_~:@/?]*)?)/gi 

这是一个:

 _^(?:(?:https?|ftp)://)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!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]))|(?:(?:[az\x{00a1}-\x{ffff}0-9]+-?)*[az\x{00a1}-\x{ffff}0-9]+)(?:\.(?:[az\x{00a1}-\x{ffff}0-9]+-?)*[az\x{00a1}-\x{ffff}0-9]+)*(?:\.(?:[az\x{00a1}-\x{ffff}]{2,})))(?::\d{2,5})?(?:/[^\s]*)?$_iuS 

我认为这是简单而高效的/^(https?:\/\/)?([\da-z\.-]+)\.([az\.]{2,6})([\/\w \.-]*)*\/?$/

尝试Regexy :: Web :: Url

r = Regexy::Web::Url.new # matches 'http://foo.com', 'www.foo.com' and 'foo.com'

 [ftp:\/\/www\/.-https:\/\/-http:\/\/][a-zA-Z0-9u00a1-uffff0]{1,3}[^ ]{1,1000} 

这在js中适用于我

 var regex = new RegExp('[ftp:\/\/www\/.-https:\/\/-http:\/\/][a-zA-Z0-9u00a1-uffff0]{1,3}[^ ]{1,1000}'); regex.exec('https://www.youtube.com/watch?v=FM7MFYoylVs&feature=youtu.be&t=20s'); 

(http|www)\S+

只要使用这个正则表达式匹配所有的网址

只是添加到东西。 我知道这并不完全直接地回答这个具体的问题,但这是我能找到的最好的地方添加这个信息。 为了达到类似的目的,我写了一个jQuery插件,但是在当前状态下(将会随着时间的推移而更新),它仍然认为像'http://abc.php'这样的地址是有效的。 但是,如果在url启动时没有http,https或ftp,它将不会返回“有效”。 虽然我应该澄清,这个jQuery方法返回一个对象,而不是一个字符串或布尔值。 该对象打破了事情,并在细分是一个。布尔值。 看完整的小提琴和测试在底部的链接。 如果你只是想抓住插件去,看看下面:

jQuery插件

 (function($){$.matchUrl||$.extend({matchUrl:function(c){var b=void 0,d="url,,scheme,,authority,path,,query,,fragment".split(","),e=/^(([^\:\/\?\#]+)\:)?(\/\/([^\/\?\#]*))?([^\?\#]*)(\?([^\#]*))?(\#(.*))?/,a={url:void 0,scheme:void 0,authority:void 0,path:void 0,query:void 0,fragment:void 0,valid:!1};"string"===typeof c&&""!=c&&(b=c.match(e));if("object"===typeof b)for(x in b)d[x]&&""!=d[x]&&(a[d[x]]=b[x]);a.scheme&&a.authority&&(a.valid=!0);return a}});})(jQuery); 

jsFiddle举例:

http://jsfiddle.net/SpYk3/e4Ank/