检测Textarea中的URL - 不寻找正则表达式

时间:2017-03-29 21:02:07

标签: javascript

我正在尝试限制某人可以添加到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;
&#13;
&#13;

使用一个空格分隔URL,它只标识第一个链接。如果添加空格以将URL分隔两个空格,则会标识两者。我不认为正则表达式是这里的问题 - 正则表达式会发现两个网址都很好。我认为,当我用空格分割textarea值时,它与创建的数组有关。

任何见解都会非常感激......我花了太多时间试图解决这个问题!

1 个答案:

答案 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"]