如果匹配不在字符串的开头,则失败
这是因为^
在比赛开始时:
/(www\.)?([^@])([a-z]*\.)(com|net|edu|org)(\.au)?(\/\S*)?$/g
js> "www.foobar.com".match(/(www\.)?([^@])([a-z]*\.)(com|net|edu|org)(\.au)?(\/\S*)?$/g)
["www.foobar.com"]
js> "aoeuaoeu foobar.com".match(/(www\.)?([^@])([a-z]*\.)(com|net|edu|org)(\.au)?(\/\S*)?$/g)
[" foobar.com"]
js> "toto@aoeuaoeu foobar.com".match(/(www\.)?([^@])([a-z]*\.)(com|net|edu|org)(\.au)?(\/\S*)?$/g)
[" foobar.com"]
js> "toto@aoeuaoeu toto@foobar.com".match(/(www\.)?([^@])([a-z]*\.)(com|net|edu|org)(\.au)?(\/\S*)?$/g)
["foobar.com"]
尽管它仍然匹配域之前的空格。而且它对域做出了错误的假设……</p>
xyz.example.org
是一个与您的正则表达式不匹配的有效域;
www.3x4mpl3.org
是一个与您的正则表达式不匹配的有效域;
example.co.uk
是一个与您的正则表达式不匹配的有效域;
ουτοπία.δπθ.gr
是一个与您的正则表达式不匹配的有效域。
什么定义了合法域名?它只是一个由点分隔的 utf-8 字符序列。它不能有两个彼此跟随的点,并且规范名称是\w\.\w\w
(因为我认为不存在单字母 tld)。
不过,我这样做的方式是简单地匹配看起来像域的所有内容,方法是使用单词边界 ( ) 获取带有点分隔符的所有文本\b
:
/\b(\w+\.)+\w+\b/g
js> "aoe toto.example.org uaoeu foo.bar aoeuaoeu".match(/\b(\w+\.)+\w+\b/g)
["toto.example.org", "foo.bar"]
js> "aoe toto@example.org toto.example.org uaoeu foo.bar aoeuaoeu".match(/\b(\w+\.)+\w+\b/g)
["example.org", "toto.example.org", "foo.bar"]
js> "aoe toto@example.org toto.example.org uaoeu foo.bar aoeuaoeu f00bar.com".match(/\b(\w+\.)+\w+\b/g)
["example.org", "toto.example.org", "foo.bar", "f00bar.com"]
然后进行第二轮检查该域是否真的存在于找到的域列表中。缺点是 javascript 中的正则表达式无法检查 unicode 字符,并且要么\b
或\w
不会接受ουτοπία.δπθ.gr
为有效域名。
在 ES6 中,有/u
修饰符,它应该适用于最新的浏览器(但到目前为止我没有测试过):
"ουτοπία.δπθ.gr aoe toto@example.org toto.example.org uaoeu foo.bar aoeuaoeu".match(/\b(\w+\.)+\w+\b/gu)
编辑:
消极的后视解决了它 - 但显然不是在 JS 中。
是的,它会:为了跳过所有电子邮件地址,这里是正则表达式实现背后的工作外观:
/(?![^@])?\b(\w+\.)+\w+\b/g
js> "aoe toto@example.org toto.example.org uaoeu foo.bar aoeuaoeu f00bar.com".match(/(?<![^@])?\b(\w+\.)+\w+\b/g)
["toto.example.org", "foo.bar", "f00bar.com"]
虽然它和 unicode 一样……但它很快就会出现在 JS 中……</p>
唯一的方法是@
在匹配的正则表达式中实际保留 ,并丢弃任何包含@的匹配:
js> "toto.net aoe toto@example.org toto.example.org uaoeu foo.bar aoeuaoeu f00bar.com".match(/@?\b\w+\.+\w+\b/g).map(function (x) { if (!x.match(/@/)) return x })
["toto.net", (void 0), "toto.example", "foo.bar", "f00bar.com"]
或者使用 ES6/JS1.7 中的新列表推导,现代浏览器中应该有它......</p>
[x for x of "toto.net aoe toto@example.org toto.example.org uaoeu foo.bar aoeuaoeu f00bar.com".match(/@?\b\w+\.+\w+\b/g) if (!x.match(/@/))];
最后一次更新:
/@?\b(\w*[^\W\d]+\w*\.+)+[^\W\d_]{2,}\b/g
> "x.y tot.toc.toc $11.00 11.com 11foo.com toto.11 toto.net aoe toto@example.org toto.example.org uaoeu foo.bar aoeuaoeu f00bar.com".match(/@?\b(\w*[^\W\d]+\w*\.+)+[^\W\d_]{2,}\b/g).filter(function (x) { if (!x.match(/@/)) return x })
[ 'tot.toc.toc',
'11foo.com',
'toto.net',
'toto.example.org',
'foo.bar',
'f00bar.com' ]