2016-02-11 77 views
14

我试图使用strsplit() R中以字符串分解为基于逗号件事情,但我不想分手括号任何东西。我认为答案是一个正则表达式,但我努力获得正确的代码。使用R中strsplit(),忽略括号

因此,例如:

x <- "This is it, isn't it (well, yes)" 
> strsplit(x, ", ") 
[[1]] 
[1] "This is it"  "isn't it (well" "yes)" 

当我想的是:

[1] "This is it"  "isn't it (well, yes)" 
+0

您尝试使用大括号'(...)'作为不可分割的块范围,并且必须将您的意图放入分割正则表达式中。这不是一个简单的任务。 – huckfinn

回答

14

我们可以使用PCRE正则表达式来FAIL遵循该)(,分裂任何,接着0或多个空间(\\s*

strsplit(x, '\\([^)]+,(*SKIP)(*FAIL)|,\\s*', perl=TRUE)[[1]] 
#[1] "This is it"   "isn't it (well, yes)" 
6

我建议用(*SKIP)(*F)另一个正则表达式忽略所有的(...)子,只有匹配的子串外的逗号:

x <- "This is it, isn't it (well, yes), and (well, this, that, and this, too)" 
strsplit(x, "\\([^()]*\\)(*SKIP)(*F)|\\h*,\\h*", perl=T) 

IDEONE demo

你可以阅读更多关于How do (*SKIP) or (*F) work on regex?这里。正则表达式匹配:

  • \( - 开口托架
  • [^()]* - 比(其他零个或多个字符,并且)
  • \) - 右括号
  • (*SKIP)(*F) - 即前进当前正则表达式索引动词到关闭托架后的位置
  • | - 或...
  • \\h*,\\h* - 包含零个或多个水平空白的逗号。
+0

你劫持了* stribizhev *的账户吗? o_O –

+0

@BhargavRao:这是我的账户,我只是改了名字。你可以每个月做一次这样:) :) –

+1

这太好了。谢谢! –

1

一种不同的方法:

添加到@ Wiktor的的样本串;

x <- "This is it, isn't it (well, yes), and (well, this, that, and this, too). Let's look, does it work?" 

现在的魔力:

> strsplit(x, ", |(?>\\(.*?\\).*?\\K(, |$))", perl = TRUE) 
[[1]] 
[1] "This is it"          
[2] "isn't it (well, yes)"        
[3] "and (well, this, that, and this, too). Let's look" 
[4] "does it work?" 

那么,如何, |(?>\\(.*?\\).*?\\K(, |$))比赛?

  • |捕获任一的基团的任一侧上,这两个
    • 左侧,字符串,
    • 和右侧,(?>\\(.*?\\).*?\\K(, |$))
      • (?> ...)套起来an atomic group,这不允许回溯重新评估它匹配的内容。
      • 在这种情况下,它会寻找一个开括号(\\(),
      • 然后从0重复到无穷大时间(*),但尽可能少(?),即.被懒惰地评估任何字符(.) 。
      • 先前.重复然后通过第一右括号(\\))限定,
      • 后跟另一个集合中的任何字符的在端部具有a \\K重复0到尽可能少(.*?
      • ,这将引发到目前为止的比赛,并设置了一场新的比赛的起点。
      • 先前.*?由捕获组((...))与|,要么
        • 选择一个实际的文本串,,限定,
        • 或移动\\K到线路,$的结束时,如果有没有更多的逗号。

*呼*

如果我的解释是混乱的,看到上面链接的文档,并检查了regex101.com,在那里你可以在上面放正则表达式(单逃脱 - \ - 代替R风格的双转义 - \\)和一个测试字符串,以查看它匹配的内容并获得它在做什么的解释。您需要在正则表达式框旁边的框中设置g(全局)修饰符,以显示所有匹配,而不仅仅显示第一个匹配。

快乐strsplit ing!

+0

非常有帮助。谢谢! –