提取R中字符串中间的字符(可能使用regex?)



我正在与regex作斗争,但我想不通。

我有一个从last.fm(www.lastfm.com)提取的投标数据库。该文件是一个.txt文件,其中每行的每一列都由超过1.7GB的","(逗号)分隔,并且有一些字符扰乱了R的读取。直到现在,我终于明白了哪里出了问题,主要问题来自其他引号中的"(引号)。

为了说明,这里有一个应用readLines时的.txt文件示例。

[1] "user,"Method Man & Redman","Da Rockwilder",0,2012,2,10,8,0,41"       
[2] "user,"Method Man & Redman","Y.O.U.",0,2012,2,10,7,56,25"             
[3] "user,"Method Man & Redman","Blackout",0,2012,2,10,7,51,53"           
[4] "user,"Chuckie","Who Is Ready To Jump (Club Mix)",0,2012,2,10,7,40,12"
[5] "user,"Opgezwolle","Volle Kracht",0,2012,2,10,7,36,31"                
[6] "user,"Opgezwolle","Ut Is Wat Het Is",0,2012,2,10,7,33,25"

基本上,这变成了一个有10列的数据框架:用户名、"艺术家"、"曲目"、喜爱(0/1)、年、月、日、小时、分钟、秒

上面的例子可以很容易地阅读,没有任何问题,但当发生这样的事情时,我会遇到问题:

[1] "user,"Fall Out Boy",""The Take Over, The Breaks Over"",0,2010,4,17,7,11,37"
[2] "user,"Gare du Nord","I Want Love 12" Remix",0,2011,6,12,19,32,33"

在第一种情况下,由于使用了双引号,曲目名称中的逗号将其分为两列,而不是10列,我得到了11列。在第二种情况下,12"使字符串"打开",直到找到类似的情况才停止。当这种情况发生时,我松开了数据帧的几行。

我想要什么作为解决方案?我想删除所有的"(引号),除了艺术家的名字和曲目的名字周围的那些。

输出:输出每行总共有四(4)"(引号)。"艺术家"one_answers"曲目名称"。所以这两行的输出会给我带来问题:

[1] "user,"Fall Out Boy","The Take Over, The Breaks Over",0,2010,4,17,7,11,37"
[2] "user,"Gare du Nord","I Want Love 12 Remix",0,2011,6,12,19,32,33"

我试着将Regex与gsub和gstring一起使用,但我无法让它只提取"多余的标记"。

如果这太复杂了,那么提取所有"除了前3个(艺术家名称周围的引号和曲目名称周围的第一个引号)和最后一个(曲目名称末尾的引号)"的东西可能适用于大多数情况(剩下的我会手动完成)。我在这里假设没有艺术家的名字包含引号。

如有任何帮助,我们将不胜感激,如果您需要任何进一步的解释或数据,请告诉我。

使用负查找来删除所有既不在前面也不在后面加逗号的"

(?<!,)\"(?!,)

演示

> x <- c('user,"Fall Out Boy",""The Take Over, The Breaks Over"",0,2010,4,17,7,11,37', 'user,"Gare du Nord","I Want Love 12" Remix",0,2011,6,12,19,32,33')
> gsub("(?<!,)\"(?!,)", "", x, perl=T)
[1] "user,"Fall Out Boy","The Take Over, The Breaks Over",0,2010,4,17,7,11,37"
[2] "user,"Gare du Nord","I Want Love 12 Remix",0,2011,6,12,19,32,33" 

请注意,模式参数中需要有一个额外的反斜杠,因为反斜杠在R和正则表达式引擎中都是转义运算符。

具有字母数字、双引号和反向引用的字符类可以做到这一点:

gsub("([ 0-9a-zA-Z"])(\")([ 0-9a-zA-Z"])", "\1\3",test)
[1] "user,"Fall Out Boy","The Take Over, The Breaks Over",0,2010,4,17,7,11,37"
[2] "user,"Gare du Nord","I Want Love 12 Remix",0,2011,6,12,19,32,33"     

也可以考虑:

gsub("([ [:alpha:][:digit:]"])(\")([ [:alpha:][:digit:]""])", 
     "\1\3", test)

基本上删除两边都有一个没有逗号的类的双引号。如果引号和正确的分隔符之间有空格,就会崩溃。这个regex页面描述了使用字符类的选项。括号是backreferences的分隔符:第一个backref是'\1',指的是第一对括号内字符类匹配的字符:([ [:alpha:][:digit:]"])。通过从替换参数中省略中间的backreference,可以消除匹配的双引号。

相关内容

  • 没有找到相关文章