2014-07-24 102 views
4

目前我正在試圖分裂在管道分隔字符串: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)" 

任何幫助讚賞。

回答

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左側失敗,迫使正則表達式引擎使用回溯控制不重試子。交替操作的右側匹配|括號外的,我們想要的東西...

+4

的確很暗。 – MrFlick

+1

+1 SKIP-FAIL – zx81

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)" 
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)" 

在這裏,我們不只是拆分對|但我們也使用向前看,以確保在下一個|或字符串的末尾沒有「)」標記。請注意,此方法不需要或確保括號是平衡的和關閉的。我們假設您的輸入格式良好。