按空格拆分字符串,除非包含在引号内

时间:2012-11-29 14:31:07

标签: regex r strsplit

我一直试图在R中用双引号拆分空格分隔的字符串一段时间但没有成功。字符串的示例如下:

降雨降雪“通道存储”“小溪存储”

这对我们很重要,因为这些列标题必须与后续数据匹配。关于如何解决这个问题,本网站还有其他一些建议,但它们似乎与R不兼容。一个例子:

Regex for splitting a string using space when not surrounded by single or double quotes

以下是我一直在尝试的一些代码:

str <- 'rainfall snowfall "Channel storage" "Rivulet storage"'
regex <- "[^\\s\"']+|\"([^\"]*)\""
split <- strsplit(str, regex, perl=T)

我想要的是

[1] "rainfall" "snowfall" "Channel storage" "Rivulet storage"

但我得到的是:

[1] ""  " " " " " "

向量是正确的长度(这是令人鼓舞的)但当然字符串是空的或包含单个空格。有什么建议吗?

提前致谢!

3 个答案:

答案 0 :(得分:15)

scan将为您执行此操作

scan(text=str, what='character', quiet=TRUE)
[1] "rainfall"        "snowfall"        "Channel storage" "Rivulet storage"

答案 1 :(得分:5)

正如mplourde所说,使用scan。这是迄今为止最干净的解决方案(除非您想保留\",即......)

如果您想使用正则表达式执行此操作(或scan无法轻松解决的问题),您仍然会以错误的方式查看它。你的正则表达式会返回你想要的东西,所以如果你在strsplit中使用它,它将会删除你想要保留的所有内容。

在这些场景中,您应该查看函数gregexp,它返回匹配的起始位置,并将匹配的长度作为属性添加。结果可以传递给函数regmatches(),如下所示:

str <- 'rainfall snowfall "Channel storage" "Rivulet storage"'
regex <- "[^\\s\"]+|\"([^\"]+)\""

regmatches(str,gregexpr(regex,str,perl=TRUE))

但是如果你只是需要角色向量作为mplourde的解决方案返回,那就去吧。而且很可能那就是你所追求的。

答案 2 :(得分:2)

您可以使用包gsubfn中的strapply。在strapply中,您可以定义匹配的字符串而不是拆分字符串。

str <- "rainfall snowfall 'Channel storage' 'Rivulet storage'"
strapply(str,"\\w+|'\\w+ \\w+'",c)[[1]]

[1] "rainfall"          "snowfall"          "'Channel storage'" "'Rivulet storage'"