假设我想提取字母a和之间的所有字母c。到目前为止,我一直在使用这个stringr软件包,它可以清楚地了解完整的比赛和分组。例如,该包将给出以下内容。
library(stringr)
str_match_all("abc", "a([a-z])c")
# [[1]]
# [,1] [,2]
# [1,] "abc" "b"
Run Code Online (Sandbox Code Playgroud)
假设我只想替换该组,而不是完整的匹配项——在本例中为字母b. 然而,以下内容将取代完整的匹配。
str_replace_all("abc", "a([a-z])c", "z")
[1] "z"
# Desired result: "azc"
Run Code Online (Sandbox Code Playgroud)
有什么好的方法可以只替换捕获组吗?假设我想做多场比赛。
str_match_all("abcdef", "a([a-z])c|d([a-z])f")
# [[1]]
# [,1] [,2] [,3]
# [1,] "abc" "b" NA
# [2,] "def" NA "e"
str_replace_all("abcdef", "a([a-z])c|d([a-z])f", "z")
# [1] "zz"
# Desired result: "azcdzf"
Run Code Online (Sandbox Code Playgroud)
匹配组很容易,但是当需要替换时我还没有找到解决方案。
这不是正则表达式的设计方式。捕获是一种获取所需字符串部分的机制,在替换时,它用于保留部分匹配项,而不是丢弃。
因此,一个自然的解决方案是将您需要保留的内容包装在捕获组中。
在这种情况下,使用
str_replace_all("abc", "(a)[a-z](c)", "\\1z\\2")
Run Code Online (Sandbox Code Playgroud)
或者使用环视(如果环视是固定/已知宽度模式):
str_replace_all("abc", "(?<=a)[a-z](?=c)", "z")
Run Code Online (Sandbox Code Playgroud)