仅替换括号之间的特定字符

Replace a specific character only between parenthesis

假设我有一个字符串:

test <- "(pop+corn)-bread+salt"

我想用'|'替换括号之间的加号,所以我得到:

"(pop|corn)-bread+salt"

我试过了:

gsub("([+])","\|",test)

但是它替换了字符串的所有加号(很明显)

我们可以试试

sub("(\([^+]+)\+","\1|", test)
#[1] "(pop|corn)-bread+salt"

如果您想替换括号内的所有 + 个符号(如果可能有 1 个 或更多 ),您可以使用以下任何一种解决方案:

gsub("\+(?=[^()]*\))", "|", x, perl=TRUE)

参见regex demo。此处,+ 仅在其后跟除 ()(带有 [^()]*)之外的任何 0+ 字符,然后是 ) 时才匹配。 只有输入是 well-formed 并且没有嵌套括号 才有用,因为它不会检查是否有起始 (.

gsub("(?:\G(?!^)|\()[^()]*?\K\+", "|", x, perl=TRUE)

这是一个更安全的解决方案,因为它仅在有起始 ( 时才开始匹配 +。参见regex demo。在此模式中,(?:\G(?!^)|\() 匹配上一个匹配项的结尾 (\G(?!^)) 或 (|) 一个 (,然后 [^()]*? 匹配其他任何 0+ 个字符比 () 字符,然后 \K 丢弃所有匹配的文本,并且 \+ 匹配将被消耗和替换的 +。它仍然不处理嵌套的括号。

此外,请参阅 online R demo for the above two solutions

library(gsubfn)
s <- "(pop(+corn)+unicorn)-bread+salt+malt"
gsubfn("\((?:[^()]++|(?R))*\)", ~ gsub("+", "|", m, fixed=TRUE), s, perl=TRUE, backref=0)
## => [1] "(pop(|corn)|unicorn)-bread+salt+malt"

这解决了匹配嵌套括号的问题,但需要 gsubfn 包。参见 another regex demo. See this regex description here

请注意,如果您不必匹配嵌套括号,则可以将 "\([^()]*\)" 正则表达式与上面的 gsubfn 代码一起使用。 \([^()]*\) 正则表达式匹配 (,然后匹配 () 以外的任何零个或多个字符(替换为 [^)]* 以匹配 )),然后).