3

我正在尝试编写一个小部件来整理来自多个来源的推文作为练习(类似的东西存在这里,但是a)那里提供的列表选项没有加载我的任何列表,并且b)这是一个有用的学习练习!)。作为其中的一部分,我想编写一个正则表达式,用指向用户 Twitter 页面的链接替换 ​​Twitter 句柄('@' 后跟字符)。但是,我不希望出现误报,例如,推文中的电子邮件地址。

因此,例如,替换应该发送

Hey there @twitteruser, my email address is address@gmail.com

Hey there <a href="http://twitter.com/twitteruser">@twitteruser</a>, my email address is address@gmail.com

在这个问题的指导下,这表明我需要某种方式在 Javascript 中复制负面的后视,我编写了以下代码:

tweetText = tweetText.replace(/(\S)?@([^\s,.;:]*)/ig, function($0, $1){
    return $1 ? $0 + '@' + $1 : '<a href="http://www.twitter.com/' + $0 + '">@' + $0 + '</a>'
});

但是,在触发三元运算符的最后部分的情况下,$0 包含“@”符号。这出乎我的意料——因为 '@' 没有括在括号中,我希望 $0 匹配 '([^\s,.;:]*)' - 即 Twitter 用户的用户名(之后,和没有,'@')。我可以通过使用 $0.substring(1) 获得所需的功能,但我想进一步了解。

有人可以指出我误解了什么吗?我对正则表达式很陌生,从来没有用 Javascript 编写过它们,也没有使用过负面的后视。

4

4 回答 4

3

在任何情况下,与其尝试在 之前匹配可选的非空格@,并在找到匹配时拒绝匹配,为什么不在 ? 之前只需要一个空格(或字符串的开头)@

tweetText = tweetText.replace(
    /(^|\s)@([^\s,.;:]*)/g,
    '$1<a href="http://www.twitter.com/$2">@$2</a>'
);

这不仅更简单,而且速度也可能更快,因为正则表达式需要考虑的潜在匹配项要少得多。

于 2012-07-01T00:02:45.063 回答
2

与大多数 REGEX 实现中的标准行为一样,匹配零是整个匹配(包括作为其中一部分的任何子匹配 - 甚至任何标记为非捕获的),然后任何后续匹配都是捕获的子匹配。查看 www.regular-expressions.info。例如:

console.log('hello, there'.match(/\w+(?:,) ?(\w+)/));

给你数组

["hello, there", "there"] //the first sub-match is non-capturing

JavaScript 不支持后视,但对此有模拟,但并不完美,就像我写的那样。JavaScript 的 REGEXP 实现总体上比其他一些语言要弱。一些遗漏的例子包括:

  • 回顾
  • 命名原子团
  • 大多数修饰符(尽管关键的修饰符在那里 - 全局,不区分大小写和多行)
  • 至关重要的是,能够在全局匹配的同时捕获子组
于 2012-06-30T23:50:46.770 回答
2

我想你可能把事情复杂化了。试试这个来检索用户名,然后创建自己的辅助函数来创建标记。

var getTwitter = function (str) {
  var re = /[^\w](@\w+)/g,
      matches = [],
      tweets = []
  while (matches = re.exec(str))
    tweets.push(matches[1])
  return tweets
}

演示:http: //jsfiddle.net/elclanrs/gLvX4/

于 2012-06-30T23:52:44.020 回答
0

你太复杂了,没那么复杂。您可以在一行代码中完成所有操作,只需执行此操作\W@(\w+)

现场演示http://jsfiddle.net/Victornpb/Wugvd/

//make twitter username links
function linkTwitterNames(elm){
    elm.innerHTML = elm.innerHTML.replace(/\W@(\w+)/g, ' <a class="twitter" href="http://twitter.com/$1" target="_blank">@$1</a>');
}
于 2013-01-20T03:06:01.897 回答