用于选择第二次出现的字符的正则表达式语法

Ahm*_*era 5 regex string syntax r

我有一个相对简单的问题,但无法找出正则表达式中的正确语法。我有多个实验名称作为各种格式的字符串,例如SEF001DT45BV004MF

我想要做的是选择数值后第二次出现的两个字母(在本例中为DTMF)。

我发现这只 [A-Z]{2} 解决了我的问题一半。如何获得正确的子字符串?

Wik*_*żew 3

TLDRPATTERN :通常,您可以使用以下方法之一获得第二次出现的 a

sub('.*?PATTERN.*?(PATTERN).*', '\\1', x)
stringr::str_match(x, 'PATTERN.*?(PATTERN)')[,2]
regmatches(x, regexpr('PATTERN.*?\\KPATTERN', x, perl=TRUE))
Run Code Online (Sandbox Code Playgroud)

细节

您可以使用

x <- c('SEF001DT45','BV004MF')
sub('.*?[A-Z]{2}.*?([A-Z]{2}).*', '\\1', x)
## => [1] "DT" "MF"
Run Code Online (Sandbox Code Playgroud)

请参阅在线 R 演示正则表达式演示。这里的要点是匹配模式的第二次出现,捕获它,然后匹配其余部分,并替换为捕获组值的反向引用。

请注意,sub将执行单个搜索和替换操作,这很好,因为这里的正则表达式需要整个字符串匹配。

细节

  • .*?- 任何零个或多个尽可能少的字符
  • [A-Z]{2}- 两个大写 ASCII 字母
  • .*?- 任何零个或多个尽可能少的字符
  • ([A-Z]{2})- 第 1 组(\1指该组值):两个大写 ASCII 字母
  • .*- 任何零个或多个尽可能多的字符。

您可以使用更简单的正则表达式来实现此目的stringr::str_match

x <- c('SEF001DT45','BV004MF')
library(stringr)
results <- stringr::str_match(x, '[A-Z]{2}.*?([A-Z]{2})')
results[,2] ## Get Group 1 values
Run Code Online (Sandbox Code Playgroud)

请参阅此 R 演示

或者,在 R 基数中使用regmatches/ :regexpr

x <- c('SEF001DT45','BV004MF')
results <- regmatches(x, regexpr('[A-Z]{2}.*?\\K[A-Z]{2}', x, perl=TRUE))
results
Run Code Online (Sandbox Code Playgroud)

请参阅此 R 演示

在这里,[A-Z]{2}.*?\\K[A-Z]{2}找到前两个大写 ASCII 字母,然后尽可能少地匹配任何零个或多个字符(除了换行符,因为使用了 PCRE 引擎),然后\K丢弃匹配的文本和[A-Z]{2}模式匹配末尾的双字母块的第二次出现。regexpr只找到第一个匹配项。