我正在尝试限制某人可以添加到textarea的网址数量。我有一个正则表达式,可以很好地找到所有的URL。以下是我遇到的问题:
当两个链接彼此相邻但由空格分隔时,我写的代码将不会识别第二个链接。如果我通过两个空格分隔它们,那么它们将被识别。我不知道这里发生了什么。
function limitLinks() {
var counter = 0;
var url = /\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/?)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\)){0,}(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s\!()\[\]{};:\'\"\.\,<>?«»“”‘’]){0,})/ig;
var sig = $(".textarea").val();
var sigsplit = sig.replace(/\n/g, " ").split(" ");
var links = [];
for (var i = 0; i < sigsplit.length; i++) {
if (url.test(sigsplit[i])) {
counter++;
links.push(sigsplit[i]);
}
}
console.log("Here's the split text:" + sigsplit);
console.log("All the links are:" + links);
}
limitLinks();
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<textarea class="textarea">foo.com bar.com</textarea>
</form>
&#13;
使用一个空格分隔URL,它只标识第一个链接。如果添加空格以将URL分隔两个空格,则会标识两者。我不认为正则表达式是这里的问题 - 正则表达式会发现两个网址都很好。我认为,当我用空格分割textarea值时,它与创建的数组有关。
任何见解都会非常感激......我花了太多时间试图解决这个问题!
答案 0 :(得分:3)
经过进一步研究,这个问题与Why RegExp with global flag in Javascript give wrong results?重复。但是我会把这个作为我的笔记保存在这里。
你的正则表达式似乎有某种&#34;记忆&#34;。
看看这个:
var url = /\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/?)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\)){0,}(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s\!()\[\]{};:\'\"\.\,<>?«»“”‘’]){0,})/ig;
function isLink(str) {
return url.test(str);
}
console.log('odd.com even.com odd.com even.com odd.com'.split(' ').filter(isLink));
返回["odd.com", "odd.com", "odd.com"]
。
现在试试这个:
function isLink(str) {
var url = /\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/?)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\)){0,}(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s\!()\[\]{};:\'\"\.\,<>?«»“”‘’]){0,})/ig;
return url.test(str);
}
console.log('odd.com even.com odd.com even.com odd.com'.split(' ').filter(isLink));
返回["odd.com", "even.com", "odd.com", "even.com", "odd.com"]
。
很有魅力,对吧?关于你的正则表达式的一些东西导致它在执行之间采取不同的行为。通过在每个函数调用上重新实例化正则表达式,它会重置该内存。很奇怪。
要解决此问题,我最后删除了g
标记。
这是一个更小的可重现的例子:
var re = /a./g;
console.log('a1 a2 a3 a4 a5 a6'.split(' ').filter(s => re.test(s)));
// returns ["a1", "a3", "a5"]
删除g
标志会返回["a1", "a2", "a3", "a4", "a5", "a6"]