วิธีที่ดีที่สุดในการจัดการไฟล์ที่มีการคั่น


16

ดังนั้นโดยทั่วไปแล้วไฟล์ CSV จะใช้เครื่องหมายจุลภาคและตัวอักษรส่งคืนเป็นฟิลด์และตัวคั่นบรรทัด

สิ่งนี้มีปัญหาชัดเจนเกี่ยวกับข้อความซึ่งอาจมีทั้งตัวละครเหล่านี้

เห็นได้ชัดว่ามีตัวเลือกอยู่ที่นั่น (หลบหนี) แต่ผู้คนจัดการกับสิ่งนี้อย่างไร ใช้อักขระที่แตกต่างกัน - ไพพ์หรือทิลดา? หลบหนีพวกเขา? ไม่ใช้ไฟล์ที่มีตัวคั่นหลังจากทั้งหมดเป็นปี 2010 และเรามี XML ตอนนี้หรือไม่

มองอย่างน้อยก็พยายามหาโอกาสที่ดีที่จะไม่เห็นปัญหา

(เพื่อความชัดเจนนี่เป็นคำถามที่เกิดจากความอยากรู้มากกว่าสิ่งที่แข็งกว่า - มันเป็นสิ่งที่ฉันได้เจอกับการเล่นข้อมูลซ้ำแล้วซ้ำอีกรอบได้เสมอ แต่มันก็รู้สึกดีสกปรก และสงสัยว่าประสบการณ์ของคนอื่นคืออะไร)


คิดอย่างรอบคอบเกี่ยวกับการใช้ CSV - เป็นเรื่องที่ดีและง่ายต่อการจัดการ (ดูคำตอบสำหรับกฎการหลบหนีทั่วไป) แต่ก็ไม่ได้เกือบจะทำงานได้อย่างที่ควรจะเป็น - ถ้าคุณแค่สื่อสารกับโปรแกรมของคุณเองก็เป็นเรื่องดี แต่ถ้าคุณ ต้องการนำเข้าที่อื่นมันแปลกเล็กน้อยเพราะโปรแกรมต่าง ๆ ปฏิบัติตามกฎการหลบหนีที่แตกต่างกัน
Michael Kohne

@Michael - อย่างแน่นอน แต่ปัญหาก็คือว่ามันอยู่ทั่วไปทุกหนทุกแห่งที่คุณมักจะเกิดขึ้นกับเวลาที่มันเป็นตัวเลือกที่ดึงดูดมากและในกรณีของระบบเก่าหลาย ๆ ตัวมันเป็นตัวเลือกเดียว
Jon Hopkins

ไลบรารีสำหรับผู้ใหญ่มีอยู่ในหลายภาษา (แน่นอนว่าเป็นเรื่องธรรมดา) สำหรับการอ่านและเขียนไฟล์ที่คั่นด้วยอักขระ พวกเขาจะจัดการกับสถานการณ์ส่วนใหญ่ การเขียนตัวแยกวิเคราะห์ CSV ของตัวเองดูเหมือนว่าจะเป็นการต่อต้านรูปแบบทั่วไป
quentin-starin

คำตอบ:


13

ตามที่Wikipedia :

ฟิลด์ที่มีเครื่องหมายจุลภาคฝังอยู่ต้องอยู่ในเครื่องหมายคำพูด

และนอกจากนี้:

ฟิลด์ที่มีอักขระเครื่องหมายคำพูดคู่แบบฝังจะต้องล้อมรอบภายในอักขระเครื่องหมายคำพูดคู่และอักขระเครื่องหมายคำพูดคู่แบบฝังแต่ละตัวจะต้องแสดงด้วยอักขระเครื่องหมายคำพูดคู่

ฉันไม่รู้ว่าใครเป็นคนคิดค้น แต่มันแสดงให้เห็นได้อย่างมีประสิทธิภาพว่าในที่สุดคุณก็ต้องหลบหนี มันเป็นทางออกที่มั่นคงเท่านั้น ทุกอย่างอื่นเป็นเพียงแค่เทปพันสายไฟที่ด้านบนของเทปพันสายไฟ: อาจจะใช้งานได้ในตอนนี้ แต่ในที่สุดคุณก็จะพบกับกรณีที่คุณต้องการข้อยกเว้นยกเว้นยกเว้นและใช้เวลาไม่นานก่อนกฎโคลนของคุณ มีความซับซ้อนกว่าวิธีแก้ปัญหาตัวละครแบบธรรมดา

ดูเหมือนว่าผู้สร้าง CSV พยายามหลีกเลี่ยงการใช้เครื่องหมายจุลภาคเป็นครั้งแรกด้วยการใช้ไวยากรณ์พิเศษที่มีเครื่องหมายคำพูดคู่ซึ่งอนุญาตให้ใช้เครื่องหมายจุลภาค แต่จากนั้นมีคนต้องการบันทึกอักขระเครื่องหมายคำพูดคู่ด้วยดังนั้นพวกเขาจึงต้องหลบหนี เครื่องหมายคำพูดสองครั้งเป็นอักขระยกเว้น หากพวกเขาตัดสินใจที่จะหลบหนีอย่างถูกต้องในตอนแรกไวยากรณ์จะง่ายขึ้นในตอนนี้


3
สิ่งที่ควรเป็นและอะไรคือสิ่งที่ .. มักจะต่างกัน :)
Tim Post

ฉันคิดว่าวิธีการแก้ปัญหาค่อนข้างโอเค สำหรับข้อมูลอย่างง่าย CSV ทำงานได้ดีสำหรับข้อมูลที่ซับซ้อนจากนั้นการอ้างเป็นสิ่งจำเป็นและหลบหนี "ด้วย" "การติดตามกลับไปที่ BASIC
Ernelli

1
@ Ernelli: ตอนนี้ฉันคิดมากกว่านี้แล้วมันอาจจะเป็นการประนีประนอมที่สมเหตุสมผลระหว่างความสามารถในการอ่านของมนุษย์และความเรียบง่าย ปัญหาการหลบหนีคือมันดูน่าเกลียดสำหรับมนุษย์แม้ว่ามันจะเป็นเรื่องเล็กน้อยสำหรับคอมพิวเตอร์ที่จะแยกวิเคราะห์ ดังนั้นการสำรอง escapes สำหรับกรณีที่หายากเท่านั้น ("เขตข้อมูลที่มีอักขระเครื่องหมายคำพูดคู่") สร้างเอาต์พุตที่มักจะอ่านได้ง่าย นี่เป็นวิธีแก้ปัญหาที่ดีโดยสมมติว่าเครื่องหมายจุลภาคในชื่อเขตข้อมูลมีการใช้บ่อยกว่าคำพูดคู่ในชื่อเขตข้อมูล
Joonas Pulakka

2

ฉันสมมติว่าคุณมีสิ่งนี้:

Foo,Baz,,,"Foo,Baz"

หากสตริงที่มีตัวคั่นไม่ได้ถูกอ้างหรือหนีคุณจะไม่มีวิธีการแยกวิเคราะห์ไฟล์ที่เชื่อถือได้จริง

อย่างไรก็ตามคุณสามารถตรวจสอบข้อมูลเพื่อแยกวิเคราะห์และสรุปได้ดังนี้:

  • เครื่องหมายจุลภาคที่คั่นด้วยเครื่องหมายจุลภาคควรถือว่าเป็นสตริง
  • หากบรรทัดก่อนหรือหลังมีตัวคั่นน้อยกว่าให้ข้ามการแยกบรรทัดนี้และบันทึก
  • รักษา 'ชอบ "

คุณต้องเขียนโปรแกรมแยกวิเคราะห์เพื่อจัดการกับสิ่งเหล่านั้น แต่มันไม่จำเป็นต้องซับซ้อน

จากประสบการณ์ของฉันการนำเข้าขยะขนาดใหญ่จากสิ่งต่าง ๆ เช่น Excel ทำให้ต้องกลับไปทบทวนและตรวจสอบลูกบอลคี่ ความท้าทายของคุณคือการให้โปรแกรมของคุณเพียงแค่สามัญสำนึกพอเกี่ยวกับข้อมูลเพื่อที่จะไม่ได้ทำแทรกบ้า จากนั้นตรวจสอบสิ่งที่บันทึกไว้และล้าง / ล้าง / ทำซ้ำ

ฉันเคยจัดการ FAQ ภายในสำหรับ บริษัท ขนาดเล็กที่ใช้เวิร์กสเตชัน Ubuntu ทั้งหมด ส่วนหนึ่งของคำถามที่พบบ่อยให้ 'เชลล์ทางลัด' และมันมาถึงฉันคั่นด้วยท่อ ดีคำตอบก็ยังมักจะคั่นด้วยท่อ (เช่น grep foo | บางอย่าง) และไม่ได้ยกมาหรือหลบหนี ฉันรู้สึกเจ็บปวดนั้น :)


2

ไม่มีอะไรผิดปกติกับ CSV จนถึงจุดหนึ่ง

CSV ทำงานได้ดีสำหรับข้อมูลที่กำหนดอย่างเหนียวแน่นซึ่งไม่น่าจะเปลี่ยนรูปแบบและไม่ได้สร้างความประหลาดใจให้กับตัวแยกวิเคราะห์ผู้รับ

นี่คือรายการ gotchas ขนาดใหญ่ที่มีประโยชน์:

  1. หนีออกจาก "" ภายใน "" (ฟิลด์มีตัวคั่นฟิลด์)
  2. "" มี CRLFs (ฟิลด์มีตัวคั่นบรรทัด)
  3. Unicode (รูปแบบข้อความพื้นฐานอาจไม่เพียงพอ)
  4. ตัวต่อสายที่แตกต่างกันสำหรับ OS ต่าง ๆ (คือ CR หรือ CRLF หรือ LF หรือ NUL)
  5. ความคิดเห็นแบบอินไลน์ (บรรทัดนำหน้าด้วย #, //, -,; ฯลฯ )
  6. การจัดการเวอร์ชั่น (ไฟล์เวอร์ชั่นล่าสุดมีฟิลด์มากหรือน้อย)
  7. ความแตกต่างระหว่าง NULL และข้อมูลว่างเปล่า (, "", ว่างเปล่า แต่ ,, เป็นโมฆะหรือไม่)

คุณสามารถเข้าใกล้สิ่งนี้ด้วยส่วนหัวเมตาดาต้าที่อธิบายวิธีการแยกวิเคราะห์ฟิลด์ แต่จากนั้นคุณอาจใช้ XML เป็นเพราะระเบียบ CSV แบบอิสระประเภทนี้ที่ถูกประดิษฐ์ขึ้น วิธี XML ดูเหมือนว่าจะมีน้ำหนักเกินกว่าที่ควรจะเป็นปัญหาง่ายๆ

ทางเลือกยอดนิยมคือกลยุทธ์ "ตัวคั่นตัวละครแปลก" สิ่งนี้ทำให้เกิดปัญหาการหลบหนีด้านบนมากมายเนื่องจากคุณใช้บางสิ่งเช่น | อักขระ (ไพพ์) สำหรับการกำหนดเขตและ CRLF สำหรับการยกเลิกเร็กคอร์ด สิ่งนี้ไม่ได้รับการแก้ไขเกี่ยวกับปัญหาเขตข้อมูลหลายบรรทัด (ยกเว้นว่าคุณใช้ตัวนับเขตข้อมูล) แต่คุณจะได้รับบรรทัดที่จัดรูปแบบเป็นอย่างดีสำหรับมนุษย์

โดยรวมแล้วหากคุณกำลังมองหาวิธีจัดการไฟล์ประเภทนี้อย่างง่ายในโลกของ Java คุณสามารถโยนOpenCSVไปได้เลย ด้วยวิธีการที่คุณสรุปปัญหาทั้งหมดลงในกรอบที่กำหนดไว้


2

CSV ยังคงเป็นรูปแบบที่ถูกต้องในหลาย ๆ สถานการณ์โดยเฉพาะอย่างยิ่งเนื่องจากต้องเป็นวิธีที่ง่ายที่สุดสำหรับลูกค้าในการเขียนข้อมูลที่ต้องนำเข้าสู่แอปพลิเคชันของคุณ ลูกค้าของเราบางคนชอบที่จะจัดการกับ XML อาจเป็นเพราะมันละเอียดมากและมีวงเล็บมุมที่ "น่ากลัว" ทั้งหมด มันง่ายกว่ามากสำหรับพวกเขาที่จะห่อสมองของพวกเขารอบ ๆ รายการที่เรียบง่ายคั่นด้วยตัวละครที่ตกลงกันไว้และยังยอมรับด้วยว่าตัวละครตัวเดียวกันจะไม่ได้รับอนุญาตในเนื้อหาของฟิลด์

ที่กล่าวว่าคุณยังต้องจัดการอินพุตอย่างถูกต้องและตรวจสอบสถานการณ์ที่พวกเขาใช้อักขระที่ไม่ถูกต้อง ฉันเริ่มใช้ FileHelpers สำหรับการแยกวิเคราะห์ CSV ของฉัน


1

ฉันปกติติดอยู่กับมาตรฐานและหลบหนีพวกเขา ในภาษาการเขียนโปรแกรมส่วนใหญ่มีการสนับสนุนในตัวที่ดีหรือมีไลบรารีที่ดี

ขึ้นอยู่กับสถานการณ์ว่าจะใช้รูปแบบใดและ CSV เป็นรูปแบบที่เหมาะสมในการแลกเปลี่ยนโครงสร้างรูปแบบข้อมูลอย่างง่าย


0

ลืม CSV ใช้JSON ง่ายต่อการเขียนและง่ายต่อการแยก XML เป็นดังนั้น 2005


6
และมีปัญหาเดียวกันเมื่อคุณต้องการใช้อักขระที่เป็นส่วนหนึ่งของรูปแบบ JSON (เช่น {หรือ,)
Salandur

Salandur: ไม่เลย! มีกฎที่แน่นอนวิธีการหลบหนี! แต่ {และไม่จำเป็นต้องหลบหนีเพราะภายในเป็นสตริงพวกมันไม่คลุมเครือ!
281377

1
ดีและดี แต่ฉันจำไม่ได้ว่า excel มีคุณลักษณะ "ส่งออกไปยัง JSON" :) มีหลายครั้งที่คุณต้องแยกวิเคราะห์สิ่งแปลก ๆ หากเพียงเพื่อให้พวกเขาอยู่ในรูปแบบที่น่าพอใจยิ่งขึ้น
Tim Post

1
และ JSON นั้นยอดเยี่ยมมากโดยสิ้นเชิงเมื่อผ่านวัตถุหลายล้านชิ้นที่มีรูปร่างเหมือนกัน โอ้เดี๋ยวก่อน
Frank Shearar

1
JSON ไม่เสนอการปรับปรุง CSV ในคำถามนี้และขาดความสามารถในการทำงานร่วมกับแอพพลิเคชั่นมากมาย (ดังที่ได้กล่าวไว้แล้วไม่สามารถนำเข้าหรือส่งออกจาก Office, SQL DBs เป็นต้น) JSON นั้นยอดเยี่ยมสำหรับการดำเนินการด้านไคลเอ็นต์น้ำหนักเบา แต่ XML นั้นดีกว่ามากสำหรับการส่งผ่านข้อมูลระหว่างแอปพลิเคชัน
Dan Diplo

0

โดยปกติสิ่งที่ฉันคิดว่าทำคือรับ TSV (ค่าที่คั่นด้วยแท็บ) แทนที่จะเป็นไฟล์ CSV ดึงไฟล์ลงใน Emacs และดูว่ามีอักขระแปลก ๆ ไม่กี่ตัวที่ไม่เคยใช้ ($ มักเป็นตัวเลือกที่ดีที่นี่) แล้วฉันจะแปลงแท็บทั้งหมดเป็น $

จากที่นั่น GNU AWK สามารถบอกให้ใช้ $ เป็นตัวคั่นฟิลด์และ Bob เป็นลุงของคุณ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.