无法替换字符串中的转义字符

时间:2016-12-15 22:53:41

标签: ruby

我有这个字符串:

str = "no,\"contact_last_name\",\"token\""
 => "no,\"contact_last_name\",\"token\""

我想删除转义的双引号字符串\"。我使用gsub

result = str.gsub('\\"','')
 => "no,\"contact_last_name\",\"token\"" 

字符串似乎没有替换字符串中的双引号转义字符。

为什么我要这样做?我有这个csv文件:

no,"contact_last_name","token",company,urbanization,sec-"property_address","property_address",city-state-zip,ase,oel,presorttrayid,presortdate,imbno,encodedimbno,fca,"property_city","property_state","property_zip"
1,MARIE A JEANTY,1083123,,,,17 SW 6TH AVE,DANIA BEACH FL 33004-3260,Electronic Service Requested,,T00215,12/14/2016,00-314-901373799-105112-33004-3260-17,TATTTADTATTDDDTTFDDFATFTDDDTTFADTTDFAAADDATDAATTFDTDFTTAFFTTATFFF,017,DANIA BEACH,FL, 33004-3260

当我尝试用CSV打开它时,出现以下错误:

CSV.foreach(path, headers: true) do |row|
end
CSV::MalformedCSVError: Illegal quoting in line 1.

一旦我删除了第一行(标题)中的双引号字符串,错误便消失了。所以我在尝试通过CSV运行之前删除那些双引号字符串:

file = File.open "file.csv"
contents = file.read
"no,\"contact_last_name\",\"token\" ... "
contents.gsub!('\\"','')

所以我的问题是为什么gsub没有删除指定的字符?请注意,这个实际确实有效:

contents.gsub /"/, ""

好像该字符串忽略了\ _字符。

2 个答案:

答案 0 :(得分:1)

字符串看起来很好;你不明白你所看到的。冥想:

"no,\"contact_last_name\",\"token\"" # => "no,\"contact_last_name\",\"token\""
'no,"contact_last_name","token"'     # => "no,\"contact_last_name\",\"token\""
%q[no,"contact_last_name","token"]   # => "no,\"contact_last_name\",\"token\""
%Q#no,"contact_last_name","token"#   # => "no,\"contact_last_name\",\"token\""

当查看由双引号分隔的字符串时,必须转义某些字符,例如嵌入的双引号。 Ruby以及许多其他语言有多种方法可以定义字符串以消除这种需求。

答案 1 :(得分:1)

此字符串中没有转义双引号:

"no,\"contact_last_name\",\"token\""

解释器将上面的文本识别为字符串,因为它用双引号括起来。并且由于同样的原因,字符串中嵌入的双引号必须被转义;否则他们发出信号结束的信号。

封闭的双引号字符是语言的一部分,而不是字符串的一部分。使用反斜杠(\)作为转义字符也是将字符放入字符串字符的方式,否则它们具有特殊含义(双引号f.e。)。

存储在str变量中的实际字符串是:

no,"contact_last_name","token"

如果您告诉口译员将字符串放在屏幕上(puts str),您可以自己检查。

要从问题标题中回答这个问题,你所有用来替换转义字符串的努力都是徒劳的,因为字符串不包含你试图查找和替换的字符序列。

实际问题是CSV文件格式错误。第一行(sec-"property_address")上的第6个值不符合正确编码的CSV文件的格式。

它应该是sec-property_address"sec-property_address";即,该值不应全部用引号括起来或完全用引号括起来。将它部分括在引号中会混淆Ruby的CSV解析器。