如果数字匹配,则使用正则表达式捕获整个子字符串

时间:2018-10-31 11:05:46

标签: r regex

我无法找到该特定问题的答案,我正在使用R清理一些调查数据。

我有一些混乱的调查数据,其中以问题名称为列,有时包括数字,有时没有。当它们包含数字时,它通常会包含一些子字符以及指示问题。例如,我有这个向量:

questions <- c(
"1 question 1 what do you think?",
"1.a. question 1a further details on what you think",
"Please explain",
"2 question 2 what is your motivation",
"2.a. further details",
"2.b. even further details",
"Please explain")

我想提取包含数字的子字符串,如果没有这样的匹配项,则不返回任何结果。所需结果(使用R)

"1"
"1.a."
NA
"2"
"2.a."
"2.b."
NA

我知道我可以使用

捕获第一个数字
 stri_extract_first_regex(questions, "[0-9]+")

但是如果使用此模式找到匹配项,如何修改它以捕获整个字符串,直到第一个空格,我都很茫然。

3 个答案:

答案 0 :(得分:1)

对于示例数据,您可以使用:

[0-9]+(?:\.[a-z]\.)?

这将匹配:

  • [0-9]+匹配1个以上的数字
  • (?:非捕获组
    • \.[a-z]\.匹配一个点,小写字符和一个点
  • )?关闭非捕获组并将其设置为可选

例如:

questions <- c(
"1 question 1 what do you think?",
"1.a. question 1a further details on what you think",
"Please explain",
"2 question 2 what is your motivation",
"2.a. further details",
"2.b. even further details",
"Please explain")

print(stri_extract_first_regex(questions, "[0-9]+(?:\\.[a-z]\\.)?"))

# [1] "1"    "1.a." NA     "2"    "2.a." "2.b." NA 

答案 1 :(得分:0)

这可能有效:

hasnumber <- grepl("[0-9]+",questions)
firstspaces <- sapply(gregexpr(" ", questions), function(x) x[[1]])
res <- ifelse(hasnumber, substr(questions,1,firstspaces-1), NA)
> res
[1] "1"    "1.a." NA     "2"    "2.a." "2.b." NA    

我猜最困难的部分是定义每个问题的第一个空格在哪里,这可以通过循环或在sapply

处完成。

答案 2 :(得分:0)

您可以使用

questions <- sub("^(\\d+(?:\\.[a-z0-9]+)*\\.?).*|.*", "\\1", questions)
questions[questions==""] <- NA
questions
# => [1] "1"    "1.a." NA     "2"    "2.a." "2.b." NA

^(\\d+(?:\\.[a-z0-9]+)*\\.?).*|.*匹配

  • ^-字符串的开头
  • (\\d+(?:\\.[a-z0-9]+)*)-捕获组1:
    • \\d+-1个以上数字
    • (?:\\.[a-z0-9]+)*-重复0次或更多次
      • \\.-一个点
      • [a-z0-9]+-1个或多个小写ASCII字母或数字
    • \\.?-可选点
  • .*-字符串末尾的任何0+个字符
  • |-或
  • .*-整个字符串。

替换组1的内容。如果第二个替代项匹配,则结果为空字符串,questions[questions==""] <- NA将这些元素替换为NA