正则表达式验证Twitter提及

13

我正在尝试寻找一个正则表达式,以匹配推文是否是真正的提及。要成为提及,字符串不能以“@”开头,也不能包含“RT”(大小写不敏感),而“@”必须在单词开头。

在示例中,我已经注释了所需的输出

一些例子:

function search($strings, $regexp) {
    $regexp;
    foreach ($strings as $string) {
        echo "Sentence: \"$string\" <- " .
        (preg_match($regexp, $string) ? "MATCH" : "NO MATCH") . "\n";
    }
}

$strings = array(
"Hi @peter, I like your car ", // <- MATCH
"@peter I don't think so!", //<- NO MATCH: the string it's starting with @ it's a reply
"Helo!! :@ how are you!", // NO MATCH <- it's not a word, we need @(word) 
"Yes @peter i'll eat them this evening! RT @peter: hey @you, do you want your pancakes?", // <- NO MATCH "RT/rt" on the string , it's a RT
"Helo!! ineed@aser.com how are you!", //<- NO MATCH, it doesn't start with @
"@peter is the best friend you could imagine. RT @juliet: @you do you know if @peter it's awesome?" // <- NO MATCH starting with @ it's a reply and RT
);
echo "Example 1:\n";
search($strings,  "/(?:[[:space:]]|^)@/i");

当前输出:

Example 1:
Sentence: "Hi @peter, I like your car " <- MATCH
Sentence: "@peter I don't think so!" <- MATCH
Sentence: "Helo!! :@ how are you!" <- NO MATCH
Sentence: "Yes @peter i'll eat them this evening! RT @peter: hey @you, do you want your pancakes?" <- MATCH
Sentence: "Helo!! ineed@aser.com how are you!" <- MATCH
Sentence: "@peter is the best friend you could imagine. RT @juliet: @you do you know if @peter it's awesome?" <- MATCH

编辑:

我需要使用正则表达式,因为它可以在MySQL和其他语言中使用。我不是在寻找任何用户名,我只想知道字符串是否为提及。


RT不区分大小写,例如在abort的末尾使用rt - hakre
"rt"必须是一个单词,并且可以后跟“:”。例如:RT|rt|rt:|RT:|rT:|都是有效的。 - LDK
“abort: now” 是一个有效的转推吗? - hakre
对于任何寻找通用模式以查找提及的人,Twitter自己使用的EXTRACT_MENTIONS模式可以在此处获得(https://github.com/twitter/twitter-text-java/blob/master/src/com/twitter/Regex.java)。 - Paul Calcraft
6个回答

13

似乎不能处理在 @ 前有空格的情况,或者在字符串中发现一个杂散的 @,后面跟着一个有效的 @mention - vhs
@JoshHabdas 嗯,当我测试你列出的两件事时,示例对我有效 - 如果您能够重现,请告诉我。 - csuwldcat
我责怪 Babel。这是我最终使用的内容,基于这个回答。(链接见原文) - vhs

9
这是一个应该有效的正则表达式:

这是一个应该有效的正则表达式:

/^(?!.*\bRT\b)(?:.+\s)?@\w+/i

解释:

/^             //start of the string
(?!.*\bRT\b)   //Verify that rt is not in the string.
(?:.*\s)?      //Find optional chars and whitespace the
                  //Note: (?: ) makes the group non-capturing.
@\w+           //Find @ followed by one or more word chars.
/i             //Make it case insensitive.

+1 对于解释,但你应该将 .*@ 改为 .+@ 以验证 @ 前至少有一个字符。 - asgerhallas
它有效了,非常感谢。但是使用新的电子邮件示例时,它匹配了,而实际上不应该匹配: 句子:Helo!! ineed@aser.com how are you! <- 匹配 - LDK
@LDK 好的,我在 @ 之前添加了一个空格字符的检查。 - Jacob Eggers
1
@Jacob,这些示例无效,但你给了我一些想法:D/^(?!.*\bRT\b).+\s@([A-Za-z0-9_])/i - LDK
[A-Za-z0-9_]与\w相同。Jacobs解决方案的问题只是他将\s放在@的错误一侧 :) - asgerhallas
1
当您在用户名中或之后使用点号(例如@user.123,这在Twitter上是允许的)时,它也会停止工作。 - Martin Erlic

3

我发现这是在JavaScript中查找字符串中提及的最佳方法。我不确定如何处理RT,但我认为这可能会有助于解决部分问题。

var str = "@jpotts18 what is up man? Are you hanging out with @kyle_clegg";
var pattern = /@[A-Za-z0-9_-]*/g;
str.match(pattern);
["@jpotts18", "@kyle_clegg"]

1

我猜这样做应该可以:

^(?!.*?RT\s).+\s@\w+

大致翻译如下:

在字符串开头,向前查找以确保不存在 RT\s,然后找到一个或多个字符,后跟 @ 和至少一个字母、数字或下划线。


现在它不匹配电子邮件。 - asgerhallas

0
一个简单但是即使爬虫工具有时添加了一些特殊字符也能正常工作的正则表达式:(?<![\w])@[\S]*\b。这对我很有效。

为什么要在字符类中放置\w\S?末尾的\b是无用的,可能会导致错误的匹配,你想匹配什么? - Toto

0

Twitter已经发布了他们在twitter-text库中使用的正则表达式。他们还在GitHub上发布了其他语言版本。


2
你的回答很好地解释了为什么我们不仅仅发布链接。你应该在这里提供带有链接的正则表达式。由于链接已经失效,你的回答变得毫无用处。 - Beau Nouvelle
我不会发布232行的代码。这是一整个类,而不是一个简单的语句。已更新链接,只花了5秒钟就找到了它。 - Jose Fernandez
又坏了。 - N. McA.

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