【问题标题】:str_extract specific patterns (example)str_extract 特定模式(示例)
【发布时间】:2014-12-03 14:18:24
【问题描述】:

我仍然对正则表达式语法有些困惑。你能帮我解决这些模式吗:

_A00_A1234B_
_A00_A12345B_
_A1_A12345_

到目前为止我的方法:

vapply(strsplit(files, "[_.]"), function(files) files[nchar(files) == 7][1], character(1))

str_extract(str2, "[A-Z][0-9]{5}[A-Z]")

预期的输出是

A1234B
A12345B
A12345

谢谢!

【问题讨论】:

  • 预期输出是什么?
  • @rkay str_extract 代码为您提供第二个元素,即。 A12345B 即。 capital letter [A-Z] 后跟5 digits 即。 [0-9]{5} 后跟大写字母 [A-Z]。第一个和第三个元素返回 NA,因为它们没有描述的模式。
  • 对不起,我忘了添加预期的输出。问题是位数不同,即4-5位,有时后面的char会丢失。
  • 好的,明白了:str_extract(files, "[A-Z][0-9]{4,5}[A-Z]")

标签: regex r


【解决方案1】:

你可以试试

library(stringr)
str_extract(str2, "[A-Z][0-9]{4,5}[A-Z]?")
#[1] "A1234B"  "A12345B" "A12345" 

在这里,该模式查找大写字母 [A-Z],后跟 4 或 5 位数字 [0-9]{4,5},后跟大写字母 [A-Z] ?

或者你可以使用stringi,这样会更快

library(stringi)
 stri_extract(str2, regex="[A-Z][0-9]{4,5}[A-Z]?")
 #[1] "A1234B"  "A12345B" "A12345" 

或者base R 选项将是

 regmatches(str2,regexpr('[A-Z][0-9]{4,5}[A-Z]?', str2))
 #[1] "A1234B"  "A12345B" "A12345" 

数据

str2 <- c('_A00_A1234B_', '_A00_A12345B_', '_A1_A12345_')

【讨论】:

    【解决方案2】:
    vec <- c("_A00_A1234B_", "_A00_A12345B_", "_A1_A12345_")
    

    您可以使用sub 和这个正则表达式:

    sub(".*([A-Z]\\d{4,5}[A-Z]?).*", "\\1", vec)
    # [1] "A1234B"  "A12345B" "A12345" 
    

    【讨论】:

      【解决方案3】:

      使用rex构造正则表达式可能更容易理解。

      x <- c("_A00_A1234B_", "_A00_A12345B_", "_A1_A12345_")
      
      # approach #1, assumes always is between the second underscores.
      re_matches(x,
        rex(
          "_",
          anything,
          "_",
          capture(anything),
          "_"
        )
      )
      
      #>         1
      #> 1  A1234B
      #> 2 A12345B
      #> 3  A12345
      
      
      # approach #2, assumes an alpha, followed by 4 or 5 digits with a possible trailing alpha.
      re_matches(x,
        rex(
          capture(
            alpha,
            between(digit, 4, 5),
            maybe(alpha)
          )
        )
      )
      
      #>         1
      #> 1  A1234B
      #> 2 A12345B
      #> 3  A12345
      

      【讨论】:

      • 我可能是错的,因为我以前从未使用过rex。所以,谢谢你介绍它。但根据您展示的语法,capture(anything) 位于第二个_ 之后。如果其中一个元素是_A1234B_A00_ 怎么办?
      • 问题并不清楚如何识别所需的元素,我从他给出的第一个示例中假设它们始终是第二部分。在rex 中执行您的正则表达式将是rex(capture(alpha, between(digit, 4, 5), maybe(alpha)))
      【解决方案4】:

      您可以在不使用正则表达式的情况下做到这一点...

      x <- c('_A00_A1234B_', '_A00_A12345B_', '_A1_A12345_')
      sapply(strsplit(x, '_', fixed=T), '[', 3)
      # [1] "A1234B"  "A12345B" "A12345" 
      

      如果你坚持使用正则表达式,以下就足够了。

      regmatches(x, regexpr('[^_]+(?=_$)', x, perl=T))
      

      【讨论】:

      • 没想到我会听到你说You can do this without using a regular expression...
      猜你喜欢
      • 1970-01-01
      • 2010-09-05
      • 1970-01-01
      • 2010-12-20
      • 2011-02-06
      • 2010-11-29
      • 1970-01-01
      • 1970-01-01
      • 2020-06-09
      相关资源
      最近更新 更多