【问题标题】:Specifying a word followed by a specific word followed by max of 3 words in regex in R在R中的正则表达式中指定一个单词后跟一个特定单词,然后是最多3个单词
【发布时间】:2020-12-22 15:22:05
【问题描述】:

我正在寻找我似乎无法获得的特定正则表达式模式:

神秘地:

pattern <- "[1 word|no word][this is][1-3 words max]"

text <- c("this guy cannot get a mortgage, this is a fake application", "this is a new application", "hi this is a specific question", "this is real", "this is not what you are looking for")

str_match("pattern", text)

我想要的输出是:

[1]FALSE  #cause too many words in front
[2]TRUE   
[3]TRUE
[4]TRUE
[5]FALSE  #cause too many words behind it

这应该是可行的,但我正在努力解决正则表达式中的单词和最大数量 谁能帮我解决这个问题?

【问题讨论】:

  • 问R为什么要加上python标签?
  • Datacrust,StackExchange 标签推荐系统还可以,但偶尔会提供不好的建议。在这种情况下,您允许它建议 python,这在问题中不建议/支持。请更加注意使用的标签; “更多”可以引起更多关注,因此更有可能获得答案,但不相关的标签可能会引起反对票、赞成票和/或只是负面回应。
  • 此外,虽然熟悉 R 包生态系统的人可能很容易推断您正在使用 stringr 包,但依赖于您并不明智在那。请明确使用非基础 R 包。如果您还没有访问过它们,有几个地方可以阅读关于如何在 SO 上很好格式化可重复和独立的问题:参考:stackoverflow.com/q/5963269minimal reproducible examplestackoverflow.com/tags/r/info .谢谢!

标签: r regex string


【解决方案1】:
grepl("^(\\S+\\s*)?this is\\s*\\S+\\s*\\S*\\s*\\S*$", text, perl = TRUE)
# [1] FALSE  TRUE  TRUE  TRUE FALSE

这似乎有点暴力,但它允许

  • ^(\\S+\\s*)? 前面零个或一个字
  • 文字this is(后跟零个或多个空格),然后
  • 至少\\S+ 一个字(至少一个字母),然后
  • 可能是空格加单词\\s*\\S*,两次,最多允许三个单词

根据您打算如何使用它,您可以使用strcapture(仍以 R 为基础)将单词提取到单列或多列中:

strcapture("^(\\S+\\s*)?this is\\s*(\\S+\\s*\\S*\\s*\\S*)$", text, 
           proto = list(ign="",w1=""), perl = TRUE)[,-1,drop=FALSE]
#                    w1
# 1                <NA>
# 2   a new application
# 3 a specific question
# 4                real
# 5                <NA>

strcapture("^(\\S+\\s*)?this is\\s*(\\S+)\\s*(\\S*)\\s*(\\S*)$", text, 
           proto = list(ign="",w1="",w2="",w3=""), perl = TRUE)[,-1,drop=FALSE]
#     w1       w2          w3
# 1 <NA>     <NA>        <NA>
# 2    a      new application
# 3    a specific    question
# 4 real                     
# 5 <NA>     <NA>        <NA>

[,-1,drop=FALSE] 是因为我们需要(..) 捕获"this is" 之前的单词,以便它可以是可选的,但我们不需要保留它们,所以我立即将它们删除。 (drop=FALSE 是因为 base R data.frame 默认将单列返回减少为向量。)


略有改进(更少的蛮力),允许以编程方式确定要接受的字数。

text2 <- c("this is one", "this is one two", "this is one two three", "this is one two three four", "this is one two three four five", "this not is", "hi this is")
grepl("^(\\S+\\s*)?this is\\s*(\\S+\\s*){1,4}$", text2, perl = TRUE)
# [1]  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE
grepl("^(\\S+\\s*)?this is\\s*(\\S+\\s*){1,2}$", text2, perl = TRUE)
# [1]  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE
grepl("^(\\S+\\s*)?this is\\s*(\\S+\\s*){1,99}$", text2, perl = TRUE)
# [1]  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE

这不一定适用于strcapture,因为它没有预定义的组数。也就是说,它只会捕获最后一个单词:

strcapture("^(\\S+\\s*)?this is\\s*(\\S+\\s*){1,3}$", text2, 
           proto = list(ign="",w1=""), perl = TRUE)
#    ign    w1
# 1        one
# 2        two
# 3      three
# 4 <NA>  <NA>
# 5 <NA>  <NA>
# 6 <NA>  <NA>
# 7 <NA>  <NA>

【讨论】:

  • 感谢 r2evans 的快速回复,它解决了我的问题,尽管它看起来确实有点暴力!
  • Datacrust,看我的编辑,略有改进。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-28
  • 2014-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多