【问题标题】:Why a pattern works for str_extract_all but does not work for strsplit nor str_subset?为什么模式适用于 str_extract_all 但不适用于 strsplit 和 str_subset?
【发布时间】:2021-11-13 13:21:20
【问题描述】:

这是我的数据,一个字符串:

data <- "Mr. NAME. Content1.Mrs. NAMEE. Content2.Ms. NAME ABCD. Content3."

我通过以下语法得到一个名称向量:

name <- unlist(str_extract_all( text, "Mr\\.\\s[:upper:]{1,20}\\s?[:upper:]{1,20}\\.|Ms\\.\\s[:upper:]{1,20}\\s?[:upper:]{1,20}\\.|Mrs\\.\\s[:upper:]{1,20}\\s?[:upper:]{1,20}\\." ))

我得到了我想要的:

名称 [1] “布克先生。” “科默先生。” “贝尔德先生。” “柯克帕特里克夫人。”
[5] “科尔特斯·马斯托女士。” “罗森女士。” “海耶斯夫人。” “莎拉拉女士。”
[9] “德奇先生。” “肯尼迪先生。” “克里希纳穆尔蒂先生。” “索托先生。”
[13] “索托先生。” “戴明斯夫人。” “索托先生。” “西西林先生。”
[17] “索托先生。” “瓦瑟曼·舒尔茨女士。” “索托先生。” “瓦瑟曼·舒尔茨女士。”

如何获得名称之间内容的向量。我想要一个这样的向量:

"Content1."   "Content2."    "Content3."

我尝试使用str_subset和strsplit来获取我在str_extract函数中定义的模式之间的内容,一次又一次失败......

【问题讨论】:

  • 这两个答案对你有用吗?
  • 是的。我将它们结合起来,得到了我想要的东西

标签: r regex text stringr


【解决方案1】:

您真的可以将您的正则表达式与stringr::str_split 一起使用。但是,将替代方案压缩为有意义的

pattern <- "\\bM(?:rs?|s)\\.\\s\\p{Lu}{1,20}\\s?\\p{Lu}{1,20}\\."

Ms、Mr 和 Mrs 可以加入 M(?:rs?|s) 模式(M,然后是 r 和可选的 s 或只是 s)。

现在,您可以将此模式与 stringr::str_split 一起使用:

pattern <- "\\bM(?:rs?|s)\\.\\s\\p{Lu}{1,20}\\s?\\p{Lu}{1,20}\\."
library(stringr)
str_split(data,pattern)
# => [[1]]
#    [1] ""           " Content1." " Content2." " Content3."

为什么开头有一个空字符串?它在那里是因为您在字符串的开头有一个匹配项。拆分时,从字符序列中删除匹配的文本,并将之前和之后的文本放入单独的项目中。当匹配开始时,第一项是空字符串。当匹配在字符串的末尾,或者有连续匹配时,也会发生同样的情况。

如果您不想在输出中包含空项目,只需将其删除:

pattern <- "\\bM(?:rs?|s)\\.\\s\\p{Lu}{1,20}\\s?\\p{Lu}{1,20}\\."
library(stringr)
result <- str_split(data,pattern)
lapply(result, function(x) x[x!=""])
# => [[1]]
#    [1] " Content1." " Content2." " Content3."

【讨论】:

    【解决方案2】:

    获得所需结果的一种简单方法是使用string_replace_all 将您的正则表达式折叠为一个令牌,然后按该令牌拆分:

    #Dropping many alternative patterns, 
    pattern = "Mr\\.\\s[:upper:]{1,20}\\s?[:upper:]{1,20}\\." #etc etc
    name <- unlist(stringr::str_replace_all( data, pattern, "xyx"))
    stringr::str_split(name, "xyx")
    

    产量

    ""           " Content1." " Content2." " Content3."
    

    【讨论】:

      猜你喜欢
      • 2015-10-04
      • 2017-05-08
      • 1970-01-01
      • 1970-01-01
      • 2022-08-18
      • 2021-06-18
      • 1970-01-01
      • 2012-12-27
      • 1970-01-01
      相关资源
      最近更新 更多