2012-02-01 41 views
16

我有引用的文字如何使用ruby gsub Regexp与许多匹配?

test,first,line,"you are a "kind" man",thanks 
again,second,li,"my "boss" is you",good 

内双引号的CSV文件的内容我需要更换每一个双引号之前没有或者通过“”

test,first,line,"you are a ""kind"" man",thanks 
again,second,li,"my ""boss"" is you",good 

所以“改为”用逗号成功“

我试图

x.gsub(/([^,])"([^,])/, "#{$1}\"\"#{$2}") 

b UT没有工作

回答

39

你的正则表达式需要多一点大胆,万一出现报价在第一值的开始,或在最后值的末尾:

csv = <<ENDCSV 
test,first,line,"you are a "kind" man",thanks 
again,second,li,"my "boss" is you",good 
more,""Someone" said that you're "cute"",yay 
"watch out for this",and,also,"this test case" 
ENDCSV 

puts csv.gsub(/(?<!^|,)"(?!,|$)/,'""') 
#=> test,first,line,"you are a ""kind"" man",thanks 
#=> again,second,li,"my ""boss"" is you",good 
#=> more,"""Someone"" said that you're ""cute""",yay 
#=> "watch out for this",and,also,"this test case" 

上述正则表达式是使用负回顾后和排除模式断言(锚)在红宝石1.9可用。

  • (?<!^|,) - 双引号
  • (?!,|$)发现 - - 这点紧前必须不存在或者是线(^)的开始或逗号
  • "立即这个点以下必须不存在任逗号或行尾($

作为奖励,因为您实际上并未捕获任何一方的角色,所以您不必担心在替换字符串中正确使用\1

欲了解更多信息,请参阅official Ruby regex documentation中的“锚”部分。


但是,对于你需要更换你的输出匹配的情况下,你可以使用任何的以下内容:

"hello".gsub /([aeiou])/, '<\1>'   #=> "h<e>ll<o>" 
"hello".gsub /([aeiou])/, "<\\1>"   #=> "h<e>ll<o>" 
"hello".gsub(/([aeiou])/){ |m| "<#{$1}>" } #=> "h<e>ll<o>" 

你不能在使用字符串插值替换字符串,像你一样:

"hello".gsub /([aeiou])/, "<#{$1}>" 
#=> "h<previousmatch>ll<previousmatch>" 

...因为这串插发生一次,之前gsub已经运行。使用的gsub块形式再调用用于每个匹配,在该点的全球$1已经适当地填充,并且可使用的块。


编辑:为Ruby 1.8(为什么地球上您使用的是什么?)你可以使用:

puts csv.gsub(/([^,\n\r])"([^,\n\r])/,'\1""\2') 
+0

很酷,我试图弄清楚如何在Ruby中做负面的lookbehind断言,并且无法弄清楚。 – 2012-02-01 17:09:30

+1

感谢Phrogz,它仅适用于Ruby 1.9,能否为Ruby 1.8提供建议? – 2012-02-04 16:15:25

+0

@MahmoudKhaled更新后与Ruby 1.8一起工作。 (未来,如果您需要使用如此古老的Ruby版本,请在您的问题中提及这一点。Ruby 1.9.1是1.9系列的第一个稳定版本,已于三年前发布**。 ) – Phrogz 2012-02-04 18:04:46

8

假设s是一个字符串,这将工作:

puts s.gsub(/([^,])"([^,])/, "\\1\"\"\\2") 
+2

当你在内容中使用双引号时,最好使用单引号来引用它们,比如''\ 1“”\ 2''或使用第三种形式'%' q [\ 1“”\ 2]' – tadman 2012-02-01 16:03:59

+1

我有点担心我的回答实际上不适合您的情况,因为它不处理很多事情,比如实际上是否有逗号旁边的逗号在你的数据中引用。您可能需要做一些更复杂的,不基于正则表达式的东西。 – 2012-02-01 16:04:56