r分隔符不在括号中

时间:2014-07-24 17:45:52

标签: regex r

我目前正在尝试在管道分隔符上拆分字符串:

999|150|222|(123|145)|456|12,260|(10|10000)

我不想在括号内的|上拆分,我只想在括号外分割这个字符。

这只是分裂每个|个字符,产生我不想要的结果:

x <- '999|150|222|(123|145)|456|12,260|(10|10000)'
m <- strsplit(x, '\\|')

[[1]]
[1] "999"    "150"    "222"    "(123"   "145)"   "456"    "12,260" "(10"   
[9] "10000)"

我希望得到以下结果,保留括号内的所有内容:

[[1]]
[1] "999"        "150"        "222"        "(123|145)"  "456"       
[6] "12,260"     "(10|10000)"

任何帮助表示感谢。

3 个答案:

答案 0 :(得分:11)

您可以使用perl=T和一些黑暗魔法打开PCRE

x <- '999|150|222|(123|145)|456|12,260|(10|10000)'
strsplit(x, '\\([^)]*\\)(*SKIP)(*F)|\\|', perl=T)

# [[1]]
# [1] "999"        "150"        "222"        "(123|145)"  "456"       
# [6] "12,260"     "(10|10000)"

我们的想法是在括号中跳过内容。 Live demo

alternation operator的左侧,我们匹配括号中的任何内容,使子模式失败并强制正则表达式引擎不使用回溯控制重试子字符串。交替运算符的右侧匹配|括号外,我们想要的......

答案 1 :(得分:6)

一个选项:

scan(text=gsub("\\(|\\)", "'", x), what='', sep="|")
#[1] "999"      "150"      "222"      "123|145"  "456"      "12,260"   "10|10000"

这是使用strsplit的另一种方式。这里有其他答案使用strsplit,但这似乎是最简单的模式:

strsplit(x, "\\|(?!\\d+\\))", perl=TRUE)
# [1] "999"        "150"        "222"        "(123|145)"  "456"        "12,260"     "(10|10000)"

答案 2 :(得分:3)

这似乎有效

x <- '999|150|222|(123|145)|456|12,260|(10|10000)'
m <- strsplit(x, '\\|(?=[^)]+(\\||$))', perl=T)

# [[1]]
# [1] "999"        "150"        "222"        "(123|145)"  "456"        "12,260"    
# [7] "(10|10000)"

这里我们不只是在|上拆分,但我们也使用前瞻以确保在下一个|或字符串结尾之前没有“)”标记。请注意,此方法不需要或确保括号平衡和关闭。我们假设您的输入格式正确。