1) gsubfn 这可以在没有复杂正则表达式的情况下使用 gsubfn 来完成。由点组成的正则表达式匹配单个字符。然后,对于输入字符向量中的每个字符串,pre 函数将计数器 k 初始化为 0,然后对于每个匹配 fun 运行,该字符通过 x 参数传递给它。在fun 内,计数器k 每次遇到( 时加1,每次遇到) 时减1。如果计数器不为零并且遇到逗号,则返回分号以替换逗号;否则,返回输入字符。这是向量化的,即如果输入 s 是一个字符向量,其中每个组件都应该单独处理,它也可以工作。
library(gsubfn)
p <- proto(k = 0,
pre = function(this) this$k <- 0,
fun = function(this, x) {
if (x == "(") this$k <- k + 1
if (x == ")") this$k <- k - 1
if (k && x == ",") ";" else x
})
gsubfn(".", p, s)
给予:
[1] "Oats (24%) (Rolled; Bran), Coconut (13%) (Coconut ; Preservative (220; 223)), Brown Sugar, Milk Solids, Golden Syrup (10%), Seeds (9%) (Sesame ; Sunflower), Margarine (Vegetable Oil; Water; Salt; Emulsifiers (471; Soy Lecithin); Antioxidant (307)), Glucose, Milk Choc Compound (5%) (Sugar; Vegetable Oil; Milk Solids; Cocoa Powder; Emulsifiers (Soy Lecithin; 492); Natural Flavour), Natural Flavour"
2) Base R Base R 解决方案是将输入拆分为单个字符,给出字符向量列表 L。然后为 L 的每个组件 chars 创建一个计数器向量,k,长度与chars 相同,表示到该点的( 的数量减去到该点的) 的数量。然后用分号替换与非零 k 对应的逗号,并将 chars 转换回单个字符串。就像 (1) 这适用于字符向量。
L <- strsplit(s, "")
sapply(L, function(chars) {
k <- cumsum((chars == "(") - (chars == ")"))
chars[k & chars == ","] <- ";"
paste(chars, collapse = "")
})
注意
输入字符串s如下。
s <- "Oats (24%) (Rolled, Bran), Coconut (13%) (Coconut , Preservative (220, 223)), Brown Sugar, Milk Solids, Golden Syrup (10%), Seeds (9%) (Sesame , Sunflower), Margarine (Vegetable Oil, Water, Salt, Emulsifiers (471, Soy Lecithin), Antioxidant (307)), Glucose, Milk Choc Compound (5%) (Sugar, Vegetable Oil, Milk Solids, Cocoa Powder, Emulsifiers (Soy Lecithin, 492), Natural Flavour), Natural Flavour"