如何在JavaScript中从字符串(如Twitter)中提取@提及?

19
我正在使用Node.js编写一个应用程序,允许用户在消息中相互提到(如Twitter)。我想要能够找到用户并发送通知。为了做到这一点,我需要从Node.js字符串中提取@用户名以查找提到。

有什么建议、正则表达式或问题吗?


我认为这个问题因为涉及具体语言而与众不同。我觉得参考那篇文章很好,但它并没有提供最佳答案的更新。 - jpotts18
4个回答

47
我发现这是在JavaScript中查找字符串中提及的最佳方法。
var str = "@jpotts18 what is up man? Are you hanging out with @kyle_clegg";
var pattern = /\B@[a-z0-9_-]+/gi;
str.match(pattern);
["@jpotts18", "@kyle_clegg"]

我已经有意地将其限制为大写和小写字母数字以及 (-,_) 符号,以避免可能被误认为是用户名的句点,例如 (@j.potts)。
这就是 twitter-text.js 在幕后所做的。
// Mention related regex collection
twttr.txt.regexen.validMentionPrecedingChars = /(?:^|[^a-zA-Z0-9_!#$%&*@@]|RT:?)/;
twttr.txt.regexen.atSigns = /[@@]/;
twttr.txt.regexen.validMentionOrList = regexSupplant(
    '(#{validMentionPrecedingChars})' +  // $1: Preceding character
    '(#{atSigns})' +                     // $2: At mark
    '([a-zA-Z0-9_]{1,20})' +             // $3: Screen name
    '(\/[a-zA-Z][a-zA-Z0-9_\-]{0,24})?'  // $4: List (optional)
  , 'g');
twttr.txt.regexen.endMentionMatch = regexSupplant(/^(?:#{atSigns}|[#{latinAccentChars}]|:\/\/)/);

如果您使用了更高效或更准确的内容,请告诉我。谢谢!


3
这将匹配单个 @ 符号。要防止这种情况,您可以将 * 替换为 + - Gerald Schneider
9
您可以在“@”符号之前添加单词分隔符,以确保不会意外捕获电子邮件地址:var str = "@jpotts18 你好啊?你和 @kyle_clegg 在一起吗?请通过 foo@bar.com 联系我"; str.match(/\B@[a-z0-9_-]+/gi); - Timothée Groleau
1
太棒了,Timothee!那是非常好的建议要记住。我会根据你的建议更新我的正则表达式 @TimothéeGroleau - jpotts18
太棒了!:D 感谢你的提示,非常有帮助! - Luiz Carvalho
一定要使用twitter-text.js。上面提供的简单正则表达式在很多方面都是错误的,以下是其中的一些例子:(1)连字符在用户名中无效,(2)它无法匹配字符串开头的提及,(3)它不匹配“ä@username”,而Twitter认为这是一个提及等。 - jlh
显示剩余2条评论

6
Twitter有一个库可供使用。您可以使用https://github.com/twitter/twitter-text-js链接。如果您相信它的描述,"该库提供了自动链接和提取URL、用户名、列表和主题标签。" 您可以使用npm install twitter-text在Node中使用它。虽然我知道您不需要Twitter用户名,但是同样的逻辑仍然适用,您应该能够很好地使用它(它不验证提取的用户名是否有效)。如果不能,请为自己的目的fork它可能是一个非常好的起点。编辑:我仔细查看了文档,在这里有一个完美的例子,正好是您所需要的。
var usernames = twttr.txt.extractMentions("Mentioning @twitter and @jack")
// usernames == ["twitter", "jack"]

谢谢Nick。我已经编辑了我的答案,从那个库中提取了正则表达式。我不知道有两个@符号。嗯... - jpotts18
没问题,如果你觉得这是正确的答案,请随意接受。像这样的事情经常发生,这就是为什么我总是选择使用维护良好的库来处理这样的事情,而不是自己编写代码。它可能看起来很简单,但那些(几乎)没有人知道的小细节会导致非常难以找到的错误。 - Nick Mitchinson

0

0

以下是使用 JavaScript 和 Underscore 从 Instagram 标题中提取提及内容的方法。

var _ = require('underscore');

function parseMentions(text) {
    var mentionsRegex = new RegExp('@([a-zA-Z0-9\_\.]+)', 'gim');

    var matches = text.match(mentionsRegex);
    if (matches && matches.length) {
        matches = matches.map(function(match) {
            return match.slice(1);
        });
        return _.uniq(matches);
    } else {
        return [];
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接