繁体   English   中英

R正则表达式 - 提取以@符号开头的单词

[英]R regex - extract words beginning with @ symbol

我正在尝试使用R的stringr包从推文中提取twitter句柄。 例如,假设我想要在矢量中以“A”开头的所有单词。 我可以这样做

library(stringr)

# Get all words that begin with "A"
str_extract_all(c("hAi", "hi Ahello Ame"), "(?<=\\b)A[^\\s]+")

[[1]]
character(0)

[[2]]
[1] "Ahello" "Ame"   

大。 现在让我们尝试使用“@”而不是“A”来做同样的事情

str_extract_all(c("h@i", "hi @hello @me"), "(?<=\\b)\\@[^\\s]+")

[[1]]
[1] "@i"

[[2]]
character(0)

为什么这个例子给出了我期望的相反结果以及如何解决它?

看起来你可能意味着

str_extract_all(c("h@i", "hi @hello @me", "@twitter"), "(?<=^|\\s)@[^\\s]+")
# [[1]]
# character(0)
# [[2]]
# [1] "@hello" "@me" 
# [[3]]
# [1] "@twitter"

正则表达式中的\\b是边界,它出现在“字符串中的两个字符之间,其中一个是单词字符,另一个不是单词字符。” 看到这里 由于空格和“@”都是非单词字符,因此“@”之前没有边界。

使用此修订版,您可以匹配字符串的开头或空格之后的值。

关于你的正则表达式的一些事情:

  • (?<=\\b)\\b相同,因为字边界已经是零宽度断言
  • \\@@相同,因为@不是特殊的正则表达式元字符,你不必逃避它
  • [^\\s]+\\S+相同,几乎所有的速记字符类都在正则表达式中具有否定的对应物。

所以,你的正则表达式, \\b@\\S+ ,匹配@i in h@i因为h (字母,单词字符)和@ (非字母字符,不是字母,数字或下划线)之间有一个单词边界)。 检查这个正则表达式调试器

\\b是一个模糊的模式,其含义取决于正则表达式上下文 在您的情况下,您可能希望使用\\B ,一个非字边界,即\\B@\\S+ ,它将匹配@前面带有非字char或字符串开头的@。

x <- c("h@i", "hi @hello @me")
regmatches(x, gregexpr("\\B@\\S+", x))
## => [[1]]
## character(0)
## 
## [[2]]
## [1] "@hello" "@me"   

请参阅正则表达式演示

如果你想摆脱这个\\b / \\B模糊性,使用带有字符串方法的外观或使用perl=TRUE参数的基本R regex函数来使用明确的字边界:

regmatches(x, gregexpr("(?<!\\w)@\\S+", x, perl=TRUE))
regmatches(x, gregexpr("(?<!\\S)@\\S+", x, perl=TRUE))

哪里:

  • (?<!\\w) - 一个明确的起始词边界 - 是一个负面的lookbehind,确保在当前位置或字符串开头的左边有一个非单词字符串
  • (?<!\\S) - 一个空白的起始词边界 - 是一个负面的lookbehind,它确保在当前位置或字符串开头的左边有一个空白字符。

在这里查看此正则表达式演示另一个正则表达式演示

注意,相应的右手边界是(?!\\w)(?!\\S)

上面的答案应该足够了。 如果您只想获取用户名,这将删除@符号。

str_extract_all(c("@tweeter tweet", "h@is", "tweet @tweeter2"), "(?<=\\B\\@)[^\\s]+")
[[1]]
[1] "tweeter"

[[2]]
character(0)

[[3]]
[1] "tweeter2"

虽然我不是正则表达式的专家,但似乎问题可能是@符号与单词字符不对应,因此匹配单词开头的空字符串( \\\\b )不起作用,因为有当@在该单词之前时,没有空字符串。

这里有两个很棒的正则表达式资源,以防您没有看到它们:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM