在逗号分隔文件中使用引号包裹文本

3

我有一个类似于这样的CSV文件:

Amebiasis,California,2001,Total,571,34514777,1.654,1.521,1.796
Amebiasis,California,2001,Female,176,17340743,1.015,0.871,1.176
Amebiasis,California,2001,Male,365,17174034,2.125,1.913,2.355

我需要一个脚本,可以将所有文字块封装起来,使其看起来像这样:

"Amebiasis","California",2001,"Total",571,34514777,1.654,1.521,1.796
"Amebiasis","California",2001,"Female",176,17340743,1.015,0.871,1.176
"Amebiasis","California",2001,"Male",365,17174034,2.125,1.913,2.355

我习惯于使用PHP,但欢迎使用其他语言的解决方案。

我尝试使用Excel的本地解决方案,但那给了我三个引号:

    """Amebiasis""","""California""",2001,"""Total""",571,34514777,1.654,1.521,1.796

1
当Excel输入三个双引号时,通常是因为第一个和第三个是用来转义第二个 - 当您使用“Excel本地解决方案”时,您到底在做什么?我在您的CSV中没有看到需要转义的双引号。请参见http://tools.ietf.org/html/rfc4180#section-2的第6点。 - norlesh
  • 编辑我需要格式化的单元格
  • 选择格式单元格
  • 从底部选择自定义
  • 使用公式“@”
  • 另存为CSV,逗号分隔。
- Adam
当您使用"@"时,神秘的双引号会被插入,一旦Excel写入CSV文件,它们就会被转义 - 我猜想如果您使用三重引号重新打开修改后的CSV文件,则单元格将以正常引用字符串的形式显示在Excel中。 - norlesh
3个回答

2
您可以使用PHP原生的CSV编码函数,但是需要添加一个小的辅助函数。原因是本地函数坚持遵循csv标准,该标准不要求如果没有必要的话,单元格必须被封闭起来以便通过其内容结构进行解析。
以下是一个示例:
<?php
function encodeFunc($value) { return "\"$value\""; }

$h_input = fopen('input.csv', 'r');
$h_output = fopen('output.csv', 'w');
while ($input = fgetcsv($h_input)) {
  fputcsv($h_output, array_map('encodeFunc', $input), ',', chr(0));
}
readfile('output.csv');

文件input.csv包含以下内容:

Amebiasis,California,2001,Total,571,34514777,1.654,1.521,1.796
Amebiasis,California,2001,Female,176,17340743,1.015,0.871,1.176
Amebiasis,California,2001,Male,365,17174034,2.125,1.913,2.355

文件output.csv将包含:

"Amebiasis","California","2001","Total","571","34514777","1.654","1.521","1.796"
"Amebiasis","California","2001","Female","176","17340743","1.015","0.871","1.176"
"Amebiasis","California","2001","Male","365","17174034","2.125","1.913","2.355"

顺便说一下:这种方法也适用于大文件,它可以很好地扩展,因为它不会将整个文件加载到内存中,而只是一次加载一行;-)


1
我会说:不破坏它,不需要修复。你的csv文件已经很完美了。
但是也许你需要为某些软件添加引号?
一般来说,在csv中,引号不是用来表示某些字段为文本,而是用来转义字段内的分隔符(或换行符),例如:
text1,"text2, some more",1.234,"44,25"

如果您在Excel中使用3个引号,则意味着该字段已经被引用、转义并用引号括起来了(正如@norlesh已经提到的那样)。
"""Amebiasis""","""California"""

无论做什么,都不要使用正则表达式来“修复”csv文件,因为如果字段中有分隔符或引号,这可能会破坏将来数据更新。

但是我使用的文件中真的没有任何引号。 否则就不会有任何问题。当我在Excel文件中搜索“ ”时,什么都找不到, 无论我是在Excel内部搜索还是用文本编辑器打开文件。 - Adam
@AdamDedanga - 是的,我理解了。但是为什么需要在字段中添加引号?至于“Excel的本地解决方案”,你是什么意思?必须在某个地方添加引号才能得到3。 - Danny_ds

0

你可以使用正则表达式和preg_replace来修改它。

$string = 'Amebiasis,California,2001,Total,571,34514777,1.654,1.521,1.796';
// '\b' is a word boundary
$pattern = '/\b/i';
$replacement = '"';
$newstring =  preg_replace($pattern, $replacement, $string);
//the string with quotes
echo $newstring;


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接