我目前正在尝试在管道分隔符上拆分字符串:
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)"
任何帮助表示感谢。
答案 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)"
这里我们不只是在|
上拆分,但我们也使用前瞻以确保在下一个|
或字符串结尾之前没有“)”标记。请注意,此方法不需要或确保括号平衡和关闭。我们假设您的输入格式正确。