【问题标题】:Get Twitter @Username with Regex in R在 R 中使用正则表达式获取 Twitter @Username
【发布时间】:2013-08-12 10:58:07
【问题描述】:

如何在 R 中使用正则表达式从文本字符串中提取 Twitter 用户名?

我试过了

library(stringr)

theString <- '@foobar Foobar! and @foo (@bar) but not foo@bar.com'

str_extract_all(string=theString,pattern='(?:^|(?:[^-a-zA-Z0-9_]))@([A-Za-z]+[A-Za-z0-9_]+)')

但我最终得到@foobar@foo(@bar,其中包含不需要的括号。

我怎样才能只得到@foobar@foo@bar 作为输出?

【问题讨论】:

    标签: regex r twitter


    【解决方案1】:

    这是一种适用于R 的方法:

    theString <- '@foobar Foobar! and @foo (@bar) but not foo@bar.com'
    theString1 <- unlist(strsplit(theString, " "))
    regex <- "(^|[^@\\w])@(\\w{1,15})\\b"
    idx <- grep(regex, theString1, perl = T)
    theString1[idx]
    [1] "@foobar" "@foo"    "(@bar)"
    

    如果您想在R 中使用@Jerry 的答案:

    regex <- "@([A-Za-z]+[A-Za-z0-9_]+)(?![A-Za-z0-9_]*\\.)"
    idx <- grep(regex, theString1, perl = T)
    theString1[idx]
    [1] "@foobar" "@foo"    "(@bar)" 
    

    但是,这两种方法都包含您不想要的括号。

    更新这将使您从头到尾不带括号或任何其他类型的标点符号(下划线除外,因为它们允许在用户名中使用)

    theString <- '@foobar Foobar! and @fo_o (@bar) but not foo@bar.com'
    theString1 <- unlist(strsplit(theString, " "))
    regex1 <- "(^|[^@\\w])@(\\w{1,15})\\b" # get strings with @
    regex2 <- "[^[:alnum:]@_]"             # remove all punctuation except _ and @
    users <- gsub(regex2, "", theString1[grep(regex1, theString1, perl = T)])
    users
    
    [1] "@foobar" "@fo_o"   "@bar"
    

    【讨论】:

    • +1 很高兴知道正则表达式不是无效的,尽管前瞻不会消耗字符并且从@ 开始的匹配不应该用它来抓取(。 =/而且我很沮丧,我无法获得测试环境>_
    • 是的R 有一些使用正则表达式的独特细节... 在网络上测试R 的一些选项在这里stackoverflow.com/a/13716528/1036500 Ideone 是我最喜欢这样的快速操作
    • 我尝试使用 Ideone 但它无法找到库 stringr... 否则,我可以对其进行测试。感谢您的链接!
    • 我认为它只运行基本R 并且不安装软件包或进行任何类型的网络连接。
    • @Ben 这是一个很好的解决方案。但是,如果两个用户名彼此相邻。例如@John@Ben。您的解决方案不起作用。你知道如何让它在这种情况下工作吗?
    【解决方案2】:

    @[a-zA-Z0-9_]{0,15}

    地点:

    • @ 与字符 @ 字面匹配(区分大小写)。

    • [a-zA-Z0-15] 匹配列表中存在的单个字符

    • {0,15} 量词匹配 0 到 15 次,次数为 可能,根据需要回馈

    从混合数据集中选择 twitter 用户名效果很好。

    【讨论】:

    • 您是否使用 OP 示例字符串进行了测试:'@foobar Foobar! and @foo (@bar) but not foo@bar.com'?
    • 好点,感谢您指出回到控制台
    【解决方案3】:

    尝试使用否定的lookbehind,以免在匹配中消耗字符:

    (?:^|(?<![-a-zA-Z0-9_]))@([A-Za-z]+[A-Za-z0-9_]+)
          ^^^
    

    编辑:由于看起来后向在 R 中不起作用(我在这里的某个地方发现后向在 R 上起作用,但显然不是......),试试这个:

    @([A-Za-z]+[A-Za-z0-9_]+)(?![A-Za-z0-9_]*\\.)
    

    编辑:双转义点

    EDITv3...:尝试开启 PCRE:

    str_extract_all(string=theString,perl("(?:^|(?<![-a-zA-Z0-9_]))@([A-Za-z]+[A-Za-z0-9_]+)")
    

    【讨论】:

    • 必须将 ?&lt;! 更改为 ?:! 才能使其正常工作。它获取第一个用户名,但没有其他用户名,这就是函数 str_extract_all() 应该做的事情。
    • 当我使用&lt; 而不是: 时,R 给出Error in gregexpr("(?:^|(?&lt;![-a-zA-Z0-9_]))@([A-Za-z]+[A-Za-z0-9_]+)", : invalid regular expression '(?:^|(?&lt;![-a-zA-Z0-9_]))@([A-Za-z]+[A-Za-z0-9_]+)', reason 'Invalid regexp'
    • @Chernoff 呵呵,我很确定 R 支持lookbehinds。如果是这样,根据您拥有的东西类型,您可以使用@([A-Za-z]+[A-Za-z0-9_]+)(?![A-Za-z0-9_]*\.)。这将适用于您的示例,并检查在 bar 之后出现的 . 是否为最后一个 @
    • 我不认为 R 喜欢 \.,我收到消息:Error: '\.' is an unrecognized escape in character string starting "@([A-Za-z]+[A-Za-z0-9_]+)(?![A-Za-z0-9_]*\."
    • 如果您使用的是基本的正则表达式函数,请确保指定perl=TRUE
    猜你喜欢
    • 1970-01-01
    • 2014-06-15
    • 1970-01-01
    • 2011-09-02
    • 1970-01-01
    • 1970-01-01
    • 2021-10-16
    • 1970-01-01
    • 2011-10-14
    相关资源
    最近更新 更多