การวางเครื่องหมายข้อความไว้ในรูปแบบของสตริงที่ไม่ดีหรือไม่? มีทางเลือกอื่นหรือไม่?


10

ฉันทำงานกับสตริงจำนวนมากซึ่งต้องการการจัดการอย่างมาก

ตัวอย่างเช่นฉันอาจสร้างสตริงเช่นนี้

ส่วนที่ 1
เรือ

ส่วนการ
เขียนโปรแกรมA

ส่วนที่ 2 การ
แบ่งพาร์ติชั่นสำหรับการเขียนโปรแกรม

ส่วน AA
มาตรารายการ SQL

สตริงจะใหญ่เกินไปที่จะตรวจสอบด้วยตนเองทุกส่วน ตอนนี้ฉันต้องsplitนี้stringเป็นstringlistโดยส่วนและชิ้นส่วน ฉันนึกถึงตัวเลือกสองทาง:

นิพจน์ปกติ:

QStringList sl = s.split(QRegularExpression("\n(?=Part [0-9]+|Section [A-Z]+)"));

ดูเหมือนว่าจะใช้งานได้ แต่บางครั้งมีข้อยกเว้นเกิดขึ้น (IE: Section SQL Entriesอาจแยกได้)

มิฉะนั้นสิ่งที่ฉันสามารถทำได้คือวางเครื่องหมายเมื่อฉันสร้างสตริงเริ่มต้น:

art ส่วนที่ 1
เรือ

ection ส่วน
โปรแกรมA

art
ส่วนที่2 การแบ่งพาร์ติชันสำหรับการเขียนโปรแกรม

ection
ส่วนมาตราAA ของมาตรา SQL

ซึ่งหมายความว่าการแยกสตริงจะกลายเป็นเรื่องง่าย:

QStringList sl = s.split("🚤💻"));

มีบางอย่างบอกฉันว่าสิ่งเหล่านี้ไม่ได้เป็นแบบอย่างที่ดีหรือเป็นแบบฝึกหัดการเขียนโปรแกรม แต่ฉันมีจนถึงตอนนี้ที่ไม่ได้กล่าวถึงหรือพบทางเลือกอื่น

  • หากคุณเป็นผู้จัดการโครงการของฉันคุณจะยอมรับวิธีการเหล่านี้หรือไม่?
  • ถ้าไม่คุณจะแนะนำให้ฉันทำอะไรเป็นแนวปฏิบัติที่ดีที่สุด?

6
หากโปรแกรมของคุณรู้ว่าจะวางเครื่องหมายไว้ที่ใดทำไมไม่สร้างส่วนเป็นสตริงแยกต่างหากเพื่อเริ่มต้น
Jacob Raihle

ฉันไม่คิดว่าผู้ใช้เครื่องหมายที่ไม่สามารถแปลได้ดีในการเข้ารหัสปัจจุบันของคุณเป็นความคิดที่ดี
Tulains Córdova

2
สัญลักษณ์ที่ใช้จริงนั้นไม่เกี่ยวข้องส่วนใหญ่สิ่งที่จะสร้างความแตกต่างคือไวยากรณ์ของสิ่งที่คุณพยายามแยกวิเคราะห์
jk

4
@Akiva คุณแน่ใจเกี่ยวกับผลการปฏิบัติงานหรือไม่ คุณกำลังทำงานกับข้อมูลจำนวนเท่ากันไม่ว่าในกรณีใดฉันสงสัยว่าจะมีความแตกต่างอย่างมีนัยสำคัญ เขียนฟังก์ชั่นนับพันเป็นหนึ่งฟังก์ชั่นเรียกใช้ในลูปและทำการวัด
Jacob Raihle

2
@Akiva การดึงและแทนที่องค์ประกอบในรายการควรอย่างน้อยที่สุดเมื่อเทียบกับการแยกสตริงขนาดใหญ่
Jacob Raihle

คำตอบ:


17

ไม่ใช่เรื่องดีที่จะมีการเข้ารหัสเอกสารที่ฝังตัวเป็นข้อความในสตริง คิดถึง markdown, HTML, XML, JSON, YAML, LaTeX และอื่น ๆ

การปฏิบัติที่ไม่ดีคือการปรับแต่งวงล้อ แทนที่จะเขียนโปรแกรมประมวลผลข้อความของคุณเองให้คิดถึงการใช้มาตรฐานที่มีอยู่ มีซอฟต์แวร์ฟรีมากมายที่แยกวิเคราะห์คุณและหลาย ๆ ซอฟต์แวร์มีลิขสิทธิ์แบบไม่ จำกัด ที่ให้คุณใช้ซอฟต์แวร์ดังกล่าวในซอฟต์แวร์ที่เป็นกรรมสิทธิ์ของคุณเอง


ในกรณีของฉันฉันประดิษฐ์วงล้อหากสิ่งที่ฉันพยายามทำคือการสร้างล่ามที่ไม่เหมือนใครสำหรับภาษา markdown ตัวอย่างเช่นหนึ่งในโครงการของฉันคือการตีความน้ำยางเป็น SSML ที่สามารถอ่านได้โดยหูของมนุษย์: meta.wikimedia.org/wiki/Grants:IdeaLab/... << มีช่วงท้ายของ URL นั้นมิฉะนั้นจะใช้ไม่ได้
Akiva

2
@Akiva ฉันต้องทำงานกับรูปแบบข้อความที่กำหนดเองซึ่งพัฒนาโดยที่ทำงานของฉันซึ่งพลิกโฉมวงล้อได้อย่างแท้จริง ฉันต้องรักษา 4 parsers 3 ภาษา (Javascript, Java และวัตถุประสงค์ C) สำหรับมันและมันเป็น fricking ฝันร้าย ทำสิ่งที่ถูกต้องในขณะนี้และยกเลิกการกำหนดเองนี้ไร้สาระรูปแบบข้อความ ฉันไม่สามารถเครียดพอว่าฝันร้ายของการบำรุงรักษาจะใหญ่โตเพียงไม่กี่ปีข้างหน้า ใช้รูปแบบที่มีโครงสร้าง XML, JSON และอื่น ๆ ที่มีอยู่
Chris Cirefice

@ChrisCirefice คุณช่วยยกตัวอย่างของฝันร้ายได้ไหม?
Akiva

1
@Akiva ฉันคิดว่าความจริงที่ว่าคุณต้องรักษา parser แม้แต่คนเดียว (ในกรณีของฉันหลายภาษาและในภาษาที่แตกต่างกัน) น่ากลัว รูปแบบมาตรฐานมีอยู่ด้วยเหตุผล - พวกเขาสามารถแสดงข้อมูลที่คุณต้องการ - และด้วยความพยายามเพียงเล็กน้อยในส่วนของคุณเนื่องจาก parsers เหล่านั้นได้รับการสร้างปรับปรุงและรักษาไว้ รูปแบบข้อความที่กำหนดเองยังเป็นความรู้ที่พิเศษอย่างยิ่งซึ่งหมายความว่าโดยปกติจะมีนักพัฒนาเพียงหนึ่งหรือสองคนเท่านั้นที่จะคุ้นเคยกับรูปแบบที่จะทำให้สำเร็จ ที่ควรพูดถึงปริมาณ คนส่วนใหญ่คุ้นเคยกับ CML, JSON - รู้จักรูปแบบที่กำหนดเองน้อยมาก
Chris Cirefice

1
@Akiva แน่นอน! รูปแบบมาร์กดาวน์ (สิ่งที่ SE และเว็บไซต์อื่น ๆ ใช้สำหรับการจัดรูปแบบข้อความ) ค่อนข้างเป็นมาตรฐานเช่นเดียวกับ SQL แต่มี 'รสชาติ' ที่แตกต่างกันมากมายพร้อมส่วนขยายที่กำหนดเอง (เช่น SE) มีไลบรารีมาตรฐานที่แยกวิเคราะห์ 'หลัก' จากนั้นคุณขยายไลบรารีถ้าคุณต้องการคุณสมบัติเพิ่มเติม แต่การสร้างและรักษาฟอร์แมตเตอร์ของคุณจะน่าหัวเราะ - มีอยู่แล้วหลายอย่าง (markdown, รหัส BB, ฯลฯ ) ดังนั้นทำไมบูรณาการล้อและรักษารหัสทั้งหมดที่? อาจได้เป็นอย่างดีเพียงแค่ใช้ที่มีอยู่ในห้องสมุด :)
คริส Cirefice

8

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

ส่วนที่สำคัญที่สุดของเรื่องนี้คือแต่ละส่วนยังคงไม่บุบสลายในขณะที่แต่ละส่วน "ส่วนหัว" จะต้องมีการระบุอย่างเหมาะสม

ทำไมไม่ใช้ตัวคั่นทั่วไปแต่ให้อ่านได้? สิ่งที่ต้องการ:

[SECTION]
Part 1
Boat

[SECTION]
Section A
Programming

[SECTION]
Part 2
Partitioning boats for programming.

[SECTION]
Section AA
Section SQL Entries.

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

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


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

5

คำตอบที่ยอมรับดูเหมือนจะพลาดสิ่งที่คุณเขียนในความคิดเห็น:

เหตุผลก็คือว่าฉันต้องใช้การจัดการแบบเต็มจำนวนมาก

และให้สิ่งนี้เป็นตัวอย่าง:

s.replace ("เรือ", "การเขียนโปรแกรม");

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

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

ทางเลือกการออกแบบที่ดีกว่าที่นี่คือการให้ประเภทข้อมูลนามธรรม (ใช้คลาสหากคุณต้องการ) ให้เรียกมันMyStringListและให้ชุดการทำงานพื้นฐานขนาดเล็กซึ่งช่วยให้คุณสามารถใช้ "ฟังก์ชันนับพัน" ในแง่ของการดำเนินการนั้น ตัวอย่างเช่นอาจมีทั่วไปfindและreplaceการดำเนินงานหรือการmapดำเนินงานทั่วไป นอกจากนี้คุณยังสามารถเพิ่มบางสิ่งบางอย่างเช่นการJoinToStringดำเนินการถ้าคุณต้องการรายการทั้งหมดในสตริงเดียวสำหรับวัตถุประสงค์บางอย่าง

การใช้การดำเนินการเหล่านี้คุณกลัวว่ารหัสจะซับซ้อนมากขึ้นเพราะ"ทุกสิ่งจะต้องทำในการวนซ้ำ"จะไม่มีจุดหมายเพราะforลูปเดียวที่คุณได้รับจะถูกห่อหุ้มในการดำเนินงานของประเภทข้อมูล และฉันจะไม่กังวลเกี่ยวกับประสิทธิภาพจนกว่าคุณจะมีผลกระทบต่อประสิทธิภาพที่แท้จริงและสามารถวัดได้ (ซึ่งฉันสงสัยว่าคุณจะได้รับหากคุณใช้การดำเนินการพื้นฐานอย่างถูกต้อง)


โหวตเพราะฉันทำอะไรแบบนั้นจริงๆ มันช่วยให้ฉันตั้งค่าวงเล็บที่กำหนดเองว่า<และ>และมันจะคว้าทุกอินสแตนซ์ของสตริงนั้นที่ฉันสามารถลบอินสแตนซ์ที่ฉันไม่ต้องการได้อย่างง่ายดายและจัดการมันอย่างที่ฉันต้องการ สิ่งนี้เป็นสิ่งที่ดีเพราะการแสดงออกปกติด้วยตัวเองไม่ได้จัดการกับสตริงย่อยเช่นนี้: <boat <programming>>ดีที่มีวงเล็บหลายชั้น
Akiva

1

รูปแบบที่อธิบายมีลักษณะคล้ายกับไฟล์ INI มาก:

https://en.wikipedia.org/wiki/INI_file

ในกรณีนั้นส่วนถูกล้อมรอบด้วยเครื่องหมายวงเล็บเหลี่ยม [] ดังนั้นสิ่งที่คุณอธิบายจึงสมเหตุสมผลโดยการทำเครื่องหมายส่วนในบางแบบเพื่อเพิ่มความหมายเพิ่มเติมให้กับข้อความนั้น


0

ตัวอย่างเช่นฉันอาจสร้างสตริงเช่นนี้

คำถาม: จากสิ่งที่คุณ "สร้าง" สายนี้?

จะว่าที่ง่ายขึ้นในการจัดการ?


สตริงถูกสร้างขึ้นจากการบันทึกเนื้อหาผู้ใช้จากเว็บไซต์
Akiva

1
นี่ไม่ใช่วิธีที่เชื่อถือได้ในการดึงข้อมูลจากเว็บไซต์เพียงเพราะพวกเขาเปลี่ยนแปลงและสิ่งต่าง ๆ ได้ย้ายไปรอบ ๆ หรือหายไปโดยสิ้นเชิง คุณจะดีกว่าที่จะดึงข้อมูลจาก API บางประเภทที่เผยแพร่ (และเชื่อถือได้) นอกจากนี้การใช้เว็บไซต์เชิงพาณิชย์จำนวนมากห้ามสิ่งเหล่านี้โดยเฉพาะ
Phill W.

บางครั้งฉันไม่สามารถเลือกได้ว่าข้อมูลใดมีค่าสำหรับฉันและดังนั้นจึงจำเป็นต้องทำการตรวจสอบความสมบูรณ์ของสิ่งที่คุณกำลังดูอยู่เสมอ ตัวอย่างเช่น: ฉันเขียนLaTeXถึงSSMLล่ามและหนึ่งในปัญหาคือคุณสามารถสร้างภาพที่เหมือนกันด้วยรหัสที่แตกต่างกันอย่างมากมายและดังนั้นจึงเป็นไปไม่ได้ที่จะสอดคล้องกันหากผู้ใช้เลือกวิธีที่ไม่ดีหรือลึกลับในการสร้างสูตรของเขา ทั้งหมดที่หมายถึงในตอนท้ายของวันคือคนที่ไม่ได้ใช้การฝึกฝนที่ดีจะไม่มีการตีความที่เหมาะสมของสคริปต์ของพวกเขา
Akiva
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.