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只找到第一个匹配项。