แยกสตริงตัวอักษร Python


9

ความท้าทายคือการแยกสตริงเช่น Python ทำและพิมพ์เนื้อหาของสตริง

  • อินพุต (อาร์กิวเมนต์บรรทัดรับคำสั่งหรือ stdin) : สตริงตัวอักษร (เช่น"hello") (หรือหลายตัวอักษรดูการเรียงสตริงตามตัวอักษรด้านล่าง)
  • เอาท์พุท (stdout) : เนื้อหาของสตริง (เช่นhello)

กฎสำหรับการวิเคราะห์คำสตริง:

  • สตริงตัวอักษรถูกล้อมรอบในการจับคู่คู่ของอัญประกาศเดี่ยว ( 'a'), อัญประกาศคู่ ( "a"), อัญประกาศเดี่ยวเดียว ( '''a''') หรืออัญประกาศคู่ ( """a""") การกลับเป็นซ้ำครั้งแรกของชนิดของอัญประกาศที่เปิดสตริงสิ้นสุดสตริง
  • ทับขวาหนี: \'ภายในสตริงกลายเป็น', \"กลายเป็น"และจะกลายเป็น\\ \คุณไม่จำเป็นต้องใช้เครื่องหมายแบคสแลชอื่น ๆ แบ็กสแลชที่ไม่ได้เป็นส่วนหนึ่งของลำดับการหลีกเลี่ยงยังคงเป็นแบ็กสแลช
  • การต่อข้อมูลตามตัวอักษรสตริง:เนื้อหาของตัวอักษรสตริงที่อยู่ติดกันถูกต่อกัน ยกตัวอย่างเช่นจะกลายเป็น"hello" 'world'helloworld
  • อินพุตอาจมีช่องว่างที่ไม่ได้เป็นส่วนหนึ่งของตัวอักษรใด ๆ
  • คุณไม่จำเป็นต้องสนับสนุนช่องว่างชนิดอื่น ๆ ทั้งที่อยู่ในและนอกตัวอักษร

กฎเพิ่มเติม:

  • eval, execและสิ่งที่คล้ายกันคือไม่ได้รับอนุญาตสำหรับการแยกตัวอักษรหรือบางส่วนของมัน
  • คุณอาจคิดว่าอินพุตนั้นถูกต้อง
  • คุณอาจสันนิษฐานว่ามีความยาวอินพุตได้สูงสุด 1,023 อักขระ

ตัวอย่าง:

  • "hello" ' world' -> hello world
  • """\"""'\\\A""" -> """'\\A
  • ( '''"""'''"""'''""" ) (ไม่มีวงเล็บ แต่มีช่องว่าง) -> """'''

รหัสที่สั้นที่สุดชนะ


ผลลัพธ์ที่ได้จะเป็นรูปแบบที่สามารถจัดเก็บหรือไม่ก็เพียงพอที่จะพิมพ์และทำกับมันได้หรือไม่
DavidC

@ David Printing มันคือทั้งหมดที่คุณต้องทำ
flornquake

ดังนั้นใน (เช่น) "\ z" รหัสจำเป็นต้องใช้เป็นพิเศษในการส่งออกแบ็กสแลชและ z? แต่ \ 'กลายเป็นเพียงเครื่องหมายอัญประกาศเดี่ยวแม้ว่ามันจะปรากฏในเครื่องหมายคำพูดคู่หรือสามคำพูด? ถูกต้องไหม
breadbox

@breadbox อย่างแน่นอน
flornquake

รหัสควรสนับสนุนสตริงดิบหรือไม่ และสิ่งที่เกี่ยวกับการต่อกันของสตริงที่ไม่ใช่แบบดิบและแบบดิบ?
Bakuriu

คำตอบ:


4

Perl, 54 ตัวอักษร

#!/usr/bin/perl -p
s/ |("""|'''|"|')((\\?.)*?)\1/$2/g;s/\\(["'\\])/$1/g

เช่นเดียวกับที่ฉันโพสต์สิ่งนี้ฉันสังเกตเห็นว่ามันเกือบจะเหมือนกับโซลูชัน Ruby ของ Jan Dvorak ในความเป็นจริงฉันคล้าย ๆ กัน แต่จริงๆแล้วฉันจะพูดว่า "จิตใจที่ยิ่งใหญ่คิดเหมือนกัน" และปล่อยให้เป็นเช่นนั้น

โปรแกรมนี้เน้นกรณีมุมแปลก ๆ ในการนับตัวอักษรในสคริปต์ Perl: จากการอ่านของฉันการมีเครื่องหมายคำพูดเดี่ยวในสคริปต์หมายความว่าฉันต้องนับ-pตัวเลือกเป็นอักขระสองตัวต่อจำนวนทั้งหมดของฉัน โดยทั่วไปเมื่อคำนวณขนาดสคริปต์ Perl ตัวอักษรเส้นประเริ่มต้นบนตัวเลือกจะถือว่าฟรีเนื่องจากเหตุผลที่ว่ามันสามารถรวมกับส่วน-eที่แนะนำโปรแกรมที่เหมาะสม ... แต่แล้วคุณต้องพิจารณาการหลบหนีพิเศษใด ๆ คุณต้องป้อนสคริปต์ในบรรทัดคำสั่ง เครื่องหมายคำพูดเดี่ยวต้องการการหลีกหนีมากมายดังนั้นเพื่อหลีกเลี่ยงการลงโทษนั้นฉันต้องนับว่าเป็นสคริปต์ที่เรียกใช้จากไฟล์และดังนั้นฉันจึงได้รับ#!/usr/bin/perlฟรี แต่ไม่มีตัวเลือกอักขระใด ๆ มันสับสนเล็กน้อย


2
หากคุณต้องการที่จะแตกต่างกัน(('|")\2{2}?)ก็มีความยาวเท่ากับ("""|'''|"|')
Peter Taylor

3

C, 178 ตัวอักษร

char*p,*q,b[1024];d;main(t){for(p=q=gets(b);*p=*q++;)
d?*p==92&!(*q-*p&&*q-34&&*q-39)?*p++=*q++:*p-d||t&&*q-d|q[1]-d?++p:
(d=0,q+=2*t):*p-32?d=*p,t=*q==d&q[1]==d,q+=2*t:0;puts(b);}

นี่คือหนึ่งในโซลูชั่น C ที่ทุกอย่างทำภายในกลุ่มผู้ประกอบการที่ประกอบไปด้วยสามส่วน

โปรแกรมทำงานโดยการคัดลอกอักขระกลับเข้าไปในบัฟเฟอร์เดียวกันเขียนทับตัวอักษร dเก็บตัวคั่นเมื่ออยู่ภายในสตริงและtเป็นจริงถ้าตัวคั่นเป็นเครื่องหมายคำพูดสามตัว


ฉันคิดว่าคุณต้องรวมการเพิ่มพิเศษของตัวแปรควบคุมการวนซ้ำ สำหรับ 'foo \\' bar 'มันให้ foo \ ar' ซึ่งดูเหมือนว่ามันจะแทนที่ \\ with \, แต่จากนั้นดำเนินการแยกวิเคราะห์ต่อไปด้วยการป้อนใหม่ \ เพื่อดูโทเค็นถัดไปเป็น \ '
จัดการ

จริงๆแล้วตัวอย่างนั้นเป็นอินพุตที่ไม่ถูกต้อง 'foo\\'อ้างถึงสตริง foo \ ซึ่งตามด้วยอักขระที่ไม่ใช่ช่องว่างหรือตัวคั่นสตริง
breadbox

อุ่ย ฉันอ่านผิดกฎข้อนั้น แน่นอนว่ารหัสของคุณถูกต้อง
จัดการ

3

ทับทิม, 74 73 ตัวอักษร

puts gets.gsub(/('''|"""|'|")((\\?.)*?)\1|./,'\2').gsub /\\([\\'"])/,'\1'

แกนที่นี่คือสอง regexes: อันแรกกำหนดขอบเขตของสตริงและเลือกเนื้อหาเท่านั้น การเปลี่ยนแปลงจะมีการลบทุกอย่างที่ไม่ได้อยู่ในสายและมันยังลดลงสตริงที่ไม่เปิดเผยแบ็กสแลชจะถือว่าเป็นทางเลือกตามด้วยอะไรก็ได้ ดังนั้น,เนื่องจาก(\\?.)เอ็นจิ้นregex จะไม่ย้อนกลับไปหาอินพุตที่ถูกต้อง (ขอบคุณ @breadbox) แบ็กสแลชเพียงอย่างเดียวจึงไม่สามารถจับคู่ได้ คำพูดได้รับการจัดการผ่านการทำซ้ำขี้เกียจ Regex ที่สองจะดึงแบ็กสแลชออกก่อนที่อักขระแต่ละตัวที่สามารถหลบหนีได้ regex ขึ้นอยู่กับเครื่องยนต์ที่จะเลือกทางเลือกซ้ายสุดก่อนเสมอ

ฉันได้พิจารณาถึงวิธีการของเครื่องจักร แต่มันกลับกลายเป็นว่าค่อนข้างใหญ่ (19 คลาส x 4 ตัวอักษร) เมื่อเทียบกับโซลูชันของ regex ฉันยังคงสามารถโพสต์เครื่องของรัฐหากใครสนใจ


ความผิดพลาดเล็กน้อยอย่างหนึ่งด้วยวิธีนี้: 'foo \\' bar 'กลายเป็น foo \ แทนที่จะเป็น' foo \ 'bar'
จัดการ

@ การจัดการสิ่งนี้ถูกต้องเว้นแต่ว่ามีบางอย่างสูญหายในการจัดรูปแบบ แบ็กสแลชแรกจะหนีอันที่สอง 'foo\\'เป็นสตริงแรกและbar'อยู่นอกบริบทสตริงเมื่ออินพุตคือ'foo\\'bar'
John Dvorak

อุ่ย ไม่มีความคิดวิธีคำนวณก่อนหน้านี้ แน่นอนมันถูกต้อง ขอโทษ
จัดการ

เมื่อฉันพยายามเรียกใช้สิ่งนี้ฉันได้รับข้อความแสดงข้อผิดพลาด: "ซ้อน *? + ใน regexp" มีเวอร์ชันขั้นต่ำหรือแฟล็กรันไทม์ที่ฉันต้องการหรือไม่
breadbox

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