เหตุใดนิพจน์ทั่วไปจึงน่าดึงดูดอย่างมาก


23

ส่วนที่ 1 , ส่วนที่2 , ฉันคิดว่าคุณคงไม่สามารถจำตัวอย่างอื่นได้ยาก

สิ่งที่: ถ้ามีมากกว่าหนึ่งวิธีในการแก้ปัญหาโปรแกรมเมอร์ PHP (ฉันมักจะเรียกดูแท็ก PHP ใน StackOverflow) จะขอความช่วยเหลือในการแก้ปัญหาที่เกี่ยวข้องกับการแสดงออกปกติ

แม้ว่าจะประหยัดน้อยลงแม้ว่าคู่มือ php จะแนะนำ ( ลิงก์ ) ให้ใช้str_replaceแทนฟังก์ชันpreg_*หรือereg_*ฟังก์ชันใด ๆเมื่อไม่จำเป็นต้องใช้กฎการแทนที่แฟนซี

มีใครบางคนสงสัยว่าทำไมสิ่งนี้ถึงเกิดขึ้น?

อย่าเข้าใจฉันผิดเพื่อนที่ดีที่สุดของฉันบางคนเป็นสำนวนปกติและฉันก็ไม่ได้ดูถูก Perl สิ่งที่ฉันไม่ได้รับคือเหตุผลที่ไม่มีทางเลือกใด ๆ แม้เมื่อ overkill ชัดเจน (regex เพื่อสลับสตริง) หรือความซับซ้อนของรหัสเพิ่มขึ้นอย่างมาก (regex สำหรับรับข้อมูลจาก html ใน PHP )


2
คุณอาจต้องการพูดในสิ่งที่คู่มือ php พูดจริง
ChrisF

1
เพราะพวกเขาซ่อนเร้นดังนั้นคุณต้องการเป็นส่วนหนึ่งของสโมสร kewl kidz สุดพิเศษหรือไม่ และส่วนใหญ่เป็นเพราะพวกเขาให้วิธีสั้น ๆ ในการแสดงการแข่งขันหรือการแยกซึ่งเป็นสิ่งที่พวกเขาทำเพื่อ แน่นอนสำหรับกรณีจำลองการแยกวิเคราะห์แบบกำหนดเองถ้าดีกว่า แต่เวลา dev ในการเขียน regex อย่างรวดเร็วนั้นเป็นประโยชน์แก่ regex
haylem

คุณเน้นส่วนที่ผิดของประโยคสุดท้ายนั้น: ส่วนที่ชั่วร้ายของมันคือ "from html" ไม่ใช่ "ใน PHP"
Izkata

คำตอบ:


20

เหตุใดนิพจน์ทั่วไปจึงน่าดึงดูดอย่างมาก

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

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

สิ่งเล็ก ๆ ที่มีพลังเวทย์มนตร์ คุณไม่สามารถปฏิเสธได้ใช่ไหม


5
+1 - สิ่งลึกลับเล็ก ๆไม่น้อย
AJ Johnson

Hobitses เป็นเล่ห์เหลี่ยม
Ben DeMott

49

เมื่อเครื่องมือเดียวที่คุณมีคือ regex ทุกปัญหาดูเหมือนว่า ^((?>[a-zA-Z\d!#$%&'*+\-/=?^_{|}~]+\x20*|"((?=[\x01-\x7f])[^"\\]|\\[\x01-\x7f])*"\x20*)*(?<angle><))?((?!\.)(?>\.?[a-zA-Z\d!#$%&'*+\-/=?^_{|}~]+)+|"((?=[\x01-\x7f])[^"\\]|\\[\x01-\x7f])*")@(((?!-)[a-zA-Z\d\-]+(?<!-)\.)+[a-zA-Z]{2,}|\[(((?(?<!\[)\.)(25[0-5]|2[0-4]\d|[01]?\d?\d)){4}|[a-zA-Z\d\-]*[a-zA-Z\d]:((?=[\x01-\x7f])[^\\\[\]]|\\[\x01-\x7f])+)\])(?(angle)>)$


16
การล่อลวงให้เลือกคำตอบนี้แข็งแกร่งมาก แต่ฉันคิดว่าฉันต้องต่อต้านเพราะมันเป็นคำถามแรกของฉันที่เปิดที่นี่และฉันต้องแสร้งทำเป็นจริงจังอยู่พักหนึ่ง
cbrandolino

1
@Dev มันทำให้รู้สึกมากมาย ความคิดเห็นของฉันเป็นเพียงวิธีที่ตลกควรจะแสดงความขอบคุณสำหรับคำตอบ
cbrandolino

17
การแข่งขันนี้เกิดอะไรขึ้นบนโลก?
Tom O'Connor

4
ฉันดันโน ... ฉันคิดว่ามันน่าจะสรุปได้ทั้งหมด ถ้าคุณรู้จัก regex และไม่รู้เกี่ยวกับวิธีอื่นคุณจะไปดูทำไม คุณมีเครื่องมือที่สามารถจัดการงานได้หากทำอย่างถูกต้อง จนกว่าพวกเขาจะเจอวิธีที่ง่ายกว่าหรือมีการบอกเกี่ยวกับมัน regex จะเป็นวิธีการแบบ catch-all แม้ว่าจะซับซ้อนกว่าที่มันต้องการก็ตาม
Aeo

4
@ Tom O'Connor ฉันคิดว่าเป็นสิ่งที่ใกล้กับ Regex สำหรับการจับคู่ที่อยู่อีเมล RFC 2822 แต่ฉันต้องถอดตัวละครสองสามตัวเพราะพวกเขากำลังทำลายล้างด้วยเครื่องหมาย
ลนนาตรอน

23

ฉันคิดว่าเป็นเพราะ:

  1. มีความกระชับอย่างน่าอัศจรรย์ (เมื่อใช้อย่างถูกต้อง) เมื่อเทียบกับรหัสที่เทียบเท่าและ
  2. พวกเขาได้รับการสนับสนุนอย่างกว้างขวางในภาษาการเขียนโปรแกรมดังนั้นนักพัฒนาส่วนใหญ่จะคุ้นเคยกับพวกเขา

3
# 2 เหมาะสม
cbrandolino

23

ในขั้นตอนก่อนหน้าของอาชีพของฉัน (เช่น pre-PHP) ฉันเป็นกูรู Perl และแง่มุมหนึ่งที่สำคัญของ Perl gurudom คือความเชี่ยวชาญในการแสดงออกปกติ

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

ในกรณีที่ไม่มีความคล่องแคล่วของ Regex คุณจะเหลือชุดค่าผสมของคำสั่งควบคุมการตัดคำสั่ง strstr และ strpos ซึ่งน่าเกลียดและยากที่จะเรียกใช้ในหัวของคุณ ฉันอยากจะสร้างหนึ่ง regex ที่สง่างามกว่าสามสิบสายของการค้นหาสายป้อนข้อมูล


2
ฉันไม่สามารถลงคะแนนได้เพียงพอ
CaffGeek

8
ฉันอยากรู้: คุณอ่าน regexp อย่างคล่องแคล่วเหมือนที่คุณเขียนหรือไม่?
peterchen

7
ฉันหวังว่าคุณจะจัดให้มีการฝึกอบรม regex เป็นประจำและ / หรือบันทึกการทำงานของโค้ดของคุณ ไม่เช่นนั้นคุณกำลังสร้างฝันร้ายสนับสนุนสำหรับเพื่อนร่วมงานของคุณ เวลาที่คุณบันทึกด้วยการเขียนว่า regex อาจหายไปหลายร้อยครั้งโดยผู้ที่พยายามทำความเข้าใจว่า "regex ที่สง่างาม" กำลังทำอะไร
Jeff Knecht

3
เยี่ยมมาก คุณสามารถได้ยินเสียงชักเย่อระหว่างความรักและความเกลียดชัง regexes ที่นี่ในความคิดเห็นเหล่านี้
Dan Ray

1
@Ben Lee: ฉันเดาอย่างนั้น - OTOH ฉันไม่เคยเจอ regex ที่แสดงความคิดเห็นในป่า ปัญหาบางอย่างกับ regexes อาจขึ้นอยู่กับทัศนคติของความเย็น
peterchen

16

ในทางตรงกันข้าม. ผู้คนกำลังจดจ่อกับregex เป็นวิธีการที่ชั่วร้ายบ่อยครั้งที่ IMO เห็นได้ชัดว่า preg_match มีการใช้งานมากเกินไปphpแต่ก็ไม่ค่อยมีความชัดเจนที่จะทำเช่นนั้น (ใน PHP)

ฉันจะไปไกลและคาดเดาว่ามันเป็น microoptimization อื่นใน php land เพื่อใช้ฟังก์ชั่นสตริง มีประโยชน์มากมายหลายอย่างและพวกมันมักเป็นตัวเลือกที่ดีกว่า แต่คุณไม่ควรหลีกเลี่ยงpreg_matchความโปรดปรานของหลาย ๆstrposและifโซ่ เพราะในทางปฏิบัติมันกลับกลายเป็นว่า libpcre มักจะเร็วกว่า PHP ที่สามารถรันลูปเพื่อค้นหาทางเลือกของสตริงเช่น

เป็นตัวอย่างล่าสุดทำให้ฉันตระหนักถึงการทดสอบว่าสตริงเป็นตัวพิมพ์เล็กทั้งหมด:

 if ($string == strtolower($string))

อ่านง่ายกว่า:

 if (!preg_match("/[A-Z]/", $string))

และคุณจะคิดว่าคนแรกจะต้องเร็วกว่าเพราะมันคือ PHP ทั้งหมด แต่ในความเป็นจริงแล้ว regex จะมองผ่านสายอักขระเพียงครั้งเดียวเท่านั้นและสามารถยกเลิกเงื่อนไขที่ถูกทอดทิ้งได้ทันทีที่พบตัวอักษรตัวพิมพ์ใหญ่ strtolower () วิธีการ แต่มองไปที่สตริงสองครั้ง First strtolower () ทำสตริงที่ซ้ำกันโดยวนซ้ำตัวอักษรแต่ละตัวเปรียบเทียบและตัวพิมพ์ใหญ่ จากนั้น==จะวนซ้ำไปตามต้นฉบับและสำเนาอีกครั้งเปรียบเทียบพวกเขาอีกครั้ง

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

(ฉันถูกล่อลวงให้เพิ่มคำพูดสนุก ๆเกี่ยวกับคำตอบที่สนุกของ @ bobinceเกี่ยวกับ xhtml-regexes และบ่อยครั้งที่มันมักจะเชื่อมโยงกันในลักษณะที่ไม่ช่วยเหลือมากและคำตอบที่มีวัตถุประสงค์ด้านล่างก็ไม่สนใจ)


1
ฉันเห็นด้วยกับตัวอย่างของคุณ ในกรณีนี้โดยเฉพาะฉันต้องการ´strtolower () ´ต่อไป: ในโค้ดที่ไม่สำคัญยิ่งกว่านั้นการเพิ่มประสิทธิภาพเวลาดำเนินการที่ยิ่งใหญ่ (เทียบกับการดำเนินการอื่น) นั้นไม่มีนัยสำคัญเว้นแต่ว่าคุณต้องการประเมินตัวพิมพ์เล็ก - Ness ของไฟล์ข้อความขนาดใหญ่ แต่ฉันไม่สามารถจินตนาการกรณีที่จะเป็นประโยชน์
cbrandolino

1
@cbrandolino: ไม่มีการสนทนา ทุกสิ่งนี้ควรเกี่ยวข้องและประเมินสำหรับลูปซ้อนกันซึ่งอาจทำให้เกิดความแตกต่างจริง
มาริโอ

4
+1 เนื่องจากผู้คนมักจะทุบตีพวกเขาอยู่เสมอมากกว่าที่พวกเขาจะได้รับการสนับสนุน
Orbling

1
ในฐานะที่เป็นหนึ่งใน "regexp bashers": มันสนุกที่จะเห็นหนึ่งซับมากหรือน้อยแสดงสิ่งที่สตริง "คู่มือ" แยกวิเคราะห์ nedds 30 บรรทัดสำหรับ อย่างไรก็ตามการบำรุงรักษาประสบในตัวอย่างที่สมจริงที่สุด นอกจากนี้เมื่อพยายามนำไปใช้กับอินพุตที่ไม่ผ่านการตรวจสอบการสร้างการวินิจฉัยที่เหมาะสมสำหรับอินพุตที่ถูกปฏิเสธต้องใช้การแสดงกายกรรมเพิ่มเติม สำหรับฉันมันเป็นรหัส "เขียนเท่านั้น" ต้นแบบ - เจ๋งสำหรับสคริปต์อย่างรวดเร็ว, sucksfor แอพระยะยาว
peterchen

1
ใครก็ตามที่ไม่ได้เขียน regexes ทั้งหมดของเขาใน/xโหมดเพื่อให้ช่องว่างสำหรับข้อศอกของการรับรู้ทางปัญญาและสำหรับความคิดเห็นที่จะอธิบายว่าทำไมสิ่งที่กำลังทำอยู่แน่นอนควรมีหูของเขากล่อง แต่สำหรับ regexes จริงของความซับซ้อนที่เหมาะสมคุณจะต้องพิจารณาถึงการใช้การออกแบบจากบนลงล่างผ่าน regexes เมื่อคุณเห็นแสงสว่างคุณจะไม่ย้อนกลับไป/@#$^^@#$^&&*)@#/หา
tchrist

8

การแสดงออกปกติน่าสนใจมากเพราะเป็นเครื่องมือที่ดีที่สุดในการแยกวิเคราะห์ภาษาปกติ

พวกเขามีข้อดีดังต่อไปนี้:

  • พวกเขามีความรัดกุม โดยทั่วไปจะใช้รหัสมากขึ้นในการแยกวิเคราะห์ภาษาปกติโดยใช้อัลกอริทึมเฉพาะที่คุณคิดขึ้นมาใหม่กว่าใช้ regexp
  • พวกเขาใช้งานได้อย่างรวดเร็ว โดยทั่วไปแล้วจะใช้เวลามากขึ้นในการเขียนโปรแกรมแยกวิเคราะห์สำหรับภาษาปกติที่เฉพาะเจาะจงโดยใช้อัลกอริทึมเฉพาะที่คุณคิดขึ้นมาแทนที่จะใช้ regexp
  • พวกเขาจะง่าย เมื่อคุณเรียนรู้ชุดของอักขระพิเศษและความหมายของพวกเขาแล้วมันเป็นเรื่องง่ายที่จะเขียน regexp (แม้ว่าจะอ่านยากขึ้นเล็กน้อย) Regexps เป็นภาษาของตัวเอง - เป็นลักษณะที่มีประโยชน์เพราะเผ่าพันธุ์ของเราพัฒนาเป็นภาษาที่ดีมาก
  • พวกเขามีความรวดเร็ว เมื่อรวบรวมแล้วพวกเขาสามารถจับคู่ความยาวสตริงNในเวลาO ( N)
  • พวกเขาจะมีความยืดหยุ่น พวกเขาสามารถจับคู่ภาษาทั่วไปและข้อมูลจำนวนมากของเราจะแสดงเป็นภาษาปกติ
  • พวกเขาเป็นที่แพร่หลาย ภาษาโปรแกรมส่วนใหญ่มีการสนับสนุน regexp ขั้นพื้นฐานไม่ว่าจะผ่านทางห้องสมุดภายนอกหรือฝังลงในภาษานั้น ๆ นอกจากนี้ยังมีความแตกต่างระหว่างภาษา regexp เองไม่มากเกินไป

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

  • ไม่เข้าใจว่าสิ่งที่พวกเขาจับคู่ไม่สามารถแสดงได้โดยใช้ regexp (เช่น HTML)
  • ขี้เกียจ (ในทางที่ไม่ดี) - พวกเขารู้จักเครื่องมือและรู้ว่ามันไม่ใช่เครื่องมือที่ดีที่สุดสำหรับสิ่งที่พวกเขากำลังทำอยู่ แต่มันจะทำงานได้โดยไม่มีปัญหา 95% ของเวลาและใช้ความพยายามในการเรียนรู้ 95% โดยเฉพาะ parser หรือเขียนหนึ่งตั้งแต่เริ่มต้น
  • พวกเขาไม่ทราบว่ามีเครื่องมือที่ดีกว่าอยู่จริง

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

ฉันเห็นด้วยกับส่วนที่เหลือ แต่เร็วและง่ายใช่ไหม เส้นโค้งการเรียนรู้สูงชัน: สำหรับผู้เริ่มต้นมันยากที่จะเข้าใจว่าทำไมการแสดงออกจึงไม่ทำงานและทุกการใช้งาน regexp ดูเหมือนจะมีความแตกต่างอย่างน้อยที่สุดดังนั้น oyu จึงต้องระวังที่คุณพยายามเรียนรู้
peterchen

ทำไมมันถึงทำให้ทุกคนสับสนในการดึง HTML ออกมาเล็กน้อยโดยแยกวิเคราะห์หน้าเว็บที่เต็มไปด้วยต้นไม้ให้กลายเป็นต้นไม้แจงเต็ม? มันโง่จริงๆ เชื่อฉันเมื่อฉันแก้ไขหน้า HTML ในviคุณเดิมพันชีวิตของคุณฉันใช้:%s/foo/bar/gcมัน ถ้ามันดีพอสำหรับการแก้ไขมันก็ดีพอสำหรับสคริปต์
tchrist

6

อืมฉันสามารถเดาได้เท่านั้น บางทีบางคนอาจพบว่าโค้ดของพวกเขา 30 บรรทัดถูกแทนที่ด้วย regex ที่ยาว 20 ตัวอักษรดังนั้นจึงรู้สึกผิดที่พวกเขาจะใช้สิ่งอื่นแทนเมื่อสามารถใช้ regex ได้


4

เหมาะสมกับความคิดของบางคน ฉันไม่ชอบพวกเขา แต่ฉันมีเพื่อนที่ดูเหมือนจะคิดใน regexps ฉันเดาว่าส่วนที่ตรงกับรูปแบบของสมองของพวกเขานั้นถูกเปิดเผยมากกว่าตรรกะที่เป็นทางการ :-)


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

1
ฉันไม่เห็นด้วยการเขียนโปรแกรมเกี่ยวข้องกับการจับคู่ตรรกะและรูปแบบสองพื้นที่ Regexps เก่งมากในการจับคู่รูปแบบและควรใช้สำหรับงานดังกล่าว ก็พูดว่า "ฉันไม่ชอบพวกเขา" คือการทิ้งเครื่องมือที่ดีสำหรับงานเฉพาะ
Orbling

@Orbling: คำถามไม่ได้มาจากพวกเขาดีหรือไม่ดี แต่ทำไมบางคนถึงมากเกินไปพวกเขาและคนอื่นไม่ทำ
Lennart Regebro

อาจเป็นคำถาม แต่คำตอบของคุณแสดงให้เห็นหนึ่งในใจประเภทอื่นที่กำลังเล่นอยู่ทั้งสอง
Orbling

ฉันไม่คิดว่า "แนะนำ" เป็นคำที่ถูกต้อง
Lennart Regebro

3

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

เมื่อวานนี้ฉันมองไปที่ API สำหรับกรอบ Javascript ใหม่ที่เป็นประกายซึ่งรองรับการพัฒนาเกม HTML5 มันมีกลไกในการอธิบายการอธิบายระบบย่อยหลักที่เกมของคุณต้องการ หนึ่งจะระบุคุณสมบัติเหล่านั้นได้อย่างไร JSON? เครื่องหมายจุดอย่างคล่องแคล่ว? อาร์เรย์หรือไม่ Nope - สตริงที่มีรายการชื่อคุณสมบัติคั่นด้วยเครื่องหมายจุลภาคและช่องว่าง ฉันสงสัยว่าจะแยกวิเคราะห์รายการนั้นอย่างไร ... ?


2

เพราะคุณสามารถเห็นสิ่งทั้งหมดในครั้งเดียว เมื่อมองเห็นสิ่งต่าง ๆ ทั้งหมดได้ง่ายขึ้นและจะดีขึ้นเสมอ มันเหมือนกับเหตุผลที่โปรแกรมเมอร์ C ++ หลายคนยังคงใช้คำสั่ง printf-type: มันไม่ใช่ typesafe (อย่างน้อย gcc สามารถตรวจสอบชนิดของคำสั่ง printf) และมันก็ไม่สวย แต่ boy มันกะทัดรัดและใช้งานได้

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

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


2

อืมคำตอบปัจจุบันมุ่งเน้นด้านเทคนิคมากเกินไปและข้อดีการอ่าน / ข้อเสีย (ซึ่งเป็นประเด็นสำคัญ) ดังนั้นให้ฉันพยายามเปลี่ยนให้เข้ากับสภาพแวดล้อม / ชุมชน PHP อีกเล็กน้อย:

  • PHP เป็น Perls เล็ก ๆ น้อย ๆน้องสาว และส่วนหนึ่งของ Perl คือการแสดงออกปกติ (พวกเขาคิดค้นสิ่งนั้นไม่ใช่พวกเขา?) ดังนั้นจึงเป็นสาเหตุหนึ่งที่ทำให้ regexps แพร่หลายใน PHP ด้วย
  • กรณีการใช้งานของ PHP เป็นบังเอิญไม่มากแตกต่างจากกรณีที่ใช้สำหรับการแสดงผลปกติ PHP ถูกใช้ในเชิงโครงสร้างสำหรับการรวมหน้า HTML เข้าด้วยกัน และ regexps ทำงานกับข้อความ (สิ่งที่ WReach พูด)
  • ไมโครเพิ่มประสิทธิภาพ ดังที่ได้กล่าวไว้ก่อนหน้านี้: ผู้ใช้ฟังก์ชั่น regexps และ / หรือสตริง PHP บ่อยครั้งหลังจากรับรู้ความเร็ว ปัญหาหลักในแวดวง PHP ไม่ใช่เฉพาะสำหรับ regexps
  • นิพจน์ทั่วไปมีอยู่แล้วภายใน ใน Python ใน Java ใน C # ใน Ruby? มีความพร้อมใช้งาน แต่ตัวยับยั้งในการโหลดโมดูลเพิ่มเติม และดูว่าใน PHP หรือ Javascript ที่เป็นคุณลักษณะหลักรูปแบบการใช้งานแตกต่างกันอย่างไร การจัดแสดงอื่น: CSS ที่มีการใช้งานบ่อยขึ้น
  • คู่มือ PHPที่ผิด มันมักจะเป็น นิพจน์ทั่วไปนั้นสามารถค้นพบได้ง่ายและฉันเลื่อนความจริงนี้ไปเพราะมันน่าเบื่อในความชัดเจน: บทเรียนทั้งหมดและหนังสือแนะนำ PHP มักสอนเกี่ยวกับนิพจน์ทั่วไป แต่ไม่สามารถให้ความรู้เกี่ยวกับกรณีการใช้งาน
  • API สตริงใน PHP รับการออกแบบโดยคนเดียวกันที่นำคุณคำพูดมายากลและ namespace \ คั่น มันครอบคลุมดีกว่า Java แต่ไม่มีเสน่ห์อย่างครบถ้วน โดยเฉพาะอย่างยิ่งถ้าสตริงสามารถเป็นสองเท่าเป็นวัตถุ (ดู Python) ฟังก์ชั่นสตริงอาจเกิน regexps

แต่นั่นก็เหมือนบันทึกข้างเคียง ฉันเชื่อว่าส่วนใหญ่เป็นเหตุผลทางด้านเทคนิคและการรับรู้ที่นำไปสู่การใช้งานมากเกินไปและ / หรือหลีกเลี่ยงการแสดงออกปกติโดยทั่วไป แต่ PHP และฐานผู้ใช้ของมันมีคุณสมบัติไม่กี่อย่างที่รวมเข้าด้วยกันและทำไมเราจึงเห็นคำถามเพิ่มเติมเกี่ยวกับเรื่องนี้ [อ้างอิงที่จำเป็น!] และพวกเขาก็มี


1

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

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


1

เหตุใดนิพจน์ทั่วไปจึงน่าดึงดูดอย่างมาก

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

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


4
ฉันชอบที่จะพูดว่าการแสดงออกปกติไม่ใช่ "ปกติ" หรือ "การแสดงออก"
Andrew Barber เมื่อ

2
พวกมันน่าเกลียดและเข้าใจยากถ้าคุณไม่เข้าใจ เมื่อคุณบรรลุเซนของ regex พวกเขาจะค่อนข้างสง่างามจริงๆ
Dan Ray

1
-1 สำหรับการตัดสินใจว่าโปรแกรมเมอร์ทุกคนต้องการที่จะคลุมเครือและไม่พิจารณาคำอธิบายอื่น ๆ ... ระบุว่าทำไมคุณคิดว่าพวกเขาน่าเกลียดหรือเข้าใจยากจะช่วยได้
Macneil

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

1
@ โกง - ฉันคิดว่าคนส่วนใหญ่ดูการแสดงออกปกติที่ซับซ้อนตัดสินใจว่าการแสดงออกปกติทั้งหมดน่าเกลียดแล้วหยุดคิด ความจริงก็คือพวกมันเป็นเครื่องมือที่สง่างามและแสดงออกอย่างมากหากคุณสามารถกำหนดอคติของคุณ BTW ด้วยเหตุผลของคุณเองโปรแกรมเมอร์จำนวนมากไม่สามารถทำพีชคณิตได้ดังนั้นพีชคณิตน่าจะเป็นสิ่งที่ชั่วร้ายโดยเนื้อแท้และควรยกเลิกเพราะมันไม่ชัดเจน
Dan Ray

0

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


0

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

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

นี่ - ฉันเดา - เป็นเหตุผลสำหรับคำพูดของ jwz "ตอนนี้พวกเขามีปัญหาสองข้อ"

ฉันเดาว่าการแสดงผลปกติของ Perl นั้นทัวริงสมบูรณ์ แต่เห็นได้ชัดว่ามันยังไม่ได้รับการพิสูจน์หรือพิสูจน์อย่างเด็ดขาด


0

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


0

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

สิ่งเดียวกันสามารถพูดเกี่ยวกับ Perl, awk, Linux และทุกอย่างที่ไม่มีปุ่มมันหรือไวยากรณ์สีดี ดังนั้นมันจึงเพิ่มความซับซ้อนให้กับ "งานเล็ก ๆ น้อย ๆ " เพียงแค่โยนลูป, สปลิต, สวิทช์, เวทย์มนตร์และนั่นคือสิ่งที่อาจทำงานได้ แต่ถ้าคุณอยู่อีกฟากหนึ่งของถนน Regexes เป็นคุ้กกี้ที่สวยงามที่ดูเหมือนเสียงสัญญาณโดยไม่มีลูปที่น่ารังเกียจ ฉันชอบพวกเขาสำหรับความยืดหยุ่นที่พวกเขาให้ เมื่อรูปแบบเพื่อให้ตรงกับการเปลี่ยนแปลงคุณเพียงแค่เปลี่ยน regex ไม่ใช่อัลกอริทึมหรือเครื่องมือ / อะไรก็ตามและมันก็ดีและทำงานได้อีกครั้ง และเนื่องจากมันเป็นสตริงมหัศจรรย์คุณสามารถวางไว้นอกซอร์สโค้ดได้หากต้องการ และอีกสิ่งหนึ่งที่ทำให้ฉันนึกถึง Perl ถ้าคุณเขียน regex ที่มี 20+ chars ยาวมันรู้สึกว่าคุณทำสำเร็จได้มาก อย่างน้อยสำหรับฉันมันก็เรียบร้อยและกะทัดรัด ฉันเป็นโปรแกรมเมอร์ที่ขี้เกียจฉันไม่ชอบเขียนโค้ดจำนวนมากที่มีการระบุและความคิดเห็นที่ดีและเพิ่มข้อบกพร่องบางอย่างในการผสม

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