5.7 命名捕捉

模式 (?:...) 包住的字符就是括号分组,但是不做反向查找。模式 (?<=...)(?<!...) 都是反向查找,它们不允许跟限制符,在 ... 也不允许出现 \C。表 5.3 展示四个反向引用

表 5.3: 环顾四周查找
符号 描述
?= 正向肯定查找
?! 正向否定查找
?<= 反向肯定查找
?<! 反向否定查找

函数 regexprgregexpr 支持命名捕捉 (named capture). 如果一个组被命名了,如 (?<first>[A-Z][a-z]+) 那么,匹配的位置是按名字返回。

下面举个例子说明,从字符串向量 notables 中获得了三组匹配 name.rex 是一段正则表达式,描述的模式是人名

## named capture
notables <- c("  Ben Franklin and Jefferson Davis",
              "\tMillard Fillmore")
# name groups 'first' and 'last'
name.rex <- "(?<first>[[:upper:]][[:lower:]]+) (?<last>[[:upper:]][[:lower:]]+)"
parsed <- regexpr(name.rex, notables, perl = TRUE)
parsed
## [1] 3 2
## attr(,"match.length")
## [1] 12 16
## attr(,"index.type")
## [1] "chars"
## attr(,"useBytes")
## [1] TRUE
## attr(,"capture.start")
##      first last
## [1,]     3    7
## [2,]     2   10
## attr(,"capture.length")
##      first last
## [1,]     3    8
## [2,]     7    8
## attr(,"capture.names")
## [1] "first" "last"

notables 是一个长度为2的字符串向量,所以获得两组匹配,捕捉到匹配开始的位置 capture.start 和匹配的长度 capture.length 都是两组,按列来看,字符 B 出现在字符串 Ben Franklin and Jefferson Davis 的第三个位置,匹配的长度 Ben 是三个字符,长度是 3,如图 5.1 所示,需要注意的是一定要设置 perl = TRUE 才能使用命名捕捉功能,函数 sub 不支持命名反向引用 Named backreferences

命名捕捉

图 5.1: 命名捕捉

Atomic grouping 原子分组, possessive qualifiers 占有限定 and conditional 条件 and recursive 递归等模式超出介绍的范围,不在此处详述,感兴趣的读者可参考,此外,插播一条漫画 5.2

正则表达式漫画

图 5.2: 正则表达式漫画

正则表达式的直观解释 https://github.com/gadenbuie/regexplain