นิพจน์ปกติ: การจับคู่กลุ่มมีประโยชน์อย่างไร


6

ฉันตัดสินใจที่จะเรียนรู้พื้นฐานการแสดงออกปกติ ฉันใช้บทเรียน Regex One ออนไลน์และฉันติดอยู่ที่lession 11อยู่พักหนึ่ง แต่ฉันคิดว่าฉันได้รับแล้ว

นี่คือภารกิจ

"เขียนนิพจน์ทั่วไปที่ตรงกับชื่อไฟล์ (ไม่รวมนามสกุล) ของไฟล์ PDF ด้านล่าง"

task            text                     capture
capture text    file_a_record_file.pdf   file_a_record_file
capture text    file_yesterday.pdf       file_yesterday
skip text       testfile_fake.pdf.tmp

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

^(file_a_record_file)\.pdf$

นี้จะตรงกับชื่อแฟ้มfile_a_record_file.pdfแต่เพียง "จับ" file_a_record_file ความแตกต่างคืออะไร ... ระหว่างการจับคู่และ "การจับภาพ" และมีประโยชน์อย่างไร? "การจับคู่กลุ่ม" เป็นอย่างไร

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

^(file_.*)\.pdf$

เนื่องจากชื่อไฟล์ทั้งสองเริ่มต้นด้วยfile_ฉันคิดว่ามันเป็นความคิดที่ดีที่จะจับคู่กับมันแล้วบอกให้ตรงกับอักขระใด ๆ ที่ตามมาจากนั้นออกจากกลุ่มด้วยวงเล็บ ("กลุ่ม" คือสิ่งที่อยู่ในวงเล็บขวา ?) และหลีกเลี่ยงจุดด้วยแบ็กสแลชและจบด้วยนามสกุลไฟล์

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

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

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

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

คำตอบ:


8

ในบทเรียนที่คุณเชื่อมโยงคุณจะถูกขอให้เขียน regex ที่จับชื่อไฟล์ของทั้งสองนี้

file_a_record_file.pdf
file_yesterday.pdf

และข้าม

testfile_fake.pdf.tmp

regex ที่ง่ายที่สุดที่จะทำคือ

(.*)\.pdf$

ซึ่งหมายความว่าตรงกับทุกอย่างที่ลงท้ายด้วย.pdfแต่จับเฉพาะชื่อไฟล์

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

echo "Hello world" | perl -ne '/(.+) (.+)/; print "$2 $1\n"'

สิ่งนี้จะพิมพ์ "world Hello" เนื่องจากวงเล็บแรกถูกจับ Helloและอันดับที่สองworldแต่เราจะพิมพ์$2 $1เพื่อให้ทั้งสองตรงกันกลับด้าน

การใช้งาน regex อื่น ๆ ช่วยให้คุณสามารถดูรูปแบบการจับใช้\1, \2ฯลฯ ตัวอย่างเช่น GNU sed:

echo "Hello world" | sed 's/\(.*\) \(.*\)/\2 \1/'

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


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

2
@ Sammy ใช่คุณถูกต้อง นอกจากนี้คุณยังสามารถใช้การอ้างอิงที่จับใน regex อื่นในภายหลังหรือการจัดการประเภทใด ๆ จริง ๆ : คัดลอกไปยังตัวแปรอื่นพิมพ์ปนมันอีกบางส่วนใช้เป็นอาร์กิวเมนต์สำหรับโปรแกรมอื่น ฯลฯ
MattDMo

@ MattDM ฉันเริ่มเห็นว่ามันจะมีประโยชน์หรือไม่ อันที่จริงนี่เป็นสิ่งที่ทรงพลังจริงๆ ไม่เพียง "จับภาพกลุ่ม" แต่โดยทั่วไปแล้ว regex แต่จริงๆแล้วมันจะขึ้นอยู่กับเครื่องมือที่คุณใช้ regex รองรับ cmd ใน Windows หรือไม่ สัญลักษณ์แทนมีลักษณะเป็น*และ?ถือว่าเป็น regex หรือไม่ อาจไม่ได้ในความรู้สึกร่วมกัน? ใน regex ฉันได้เห็นจนถึงสิ่งนี้เป็นที่รู้จัก.*และ.
Samir

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

@ Sammy การใช้งาน Windows ของ*แตกต่างกันเล็กน้อย ไม่ว่าในกรณีใดก็ตาม.*หมายถึง "จับคู่อักขระใดก็ได้จำนวนครั้ง" *เพียงหมายถึง "จำนวนครั้งใด ๆ " ?หมายถึงสิ่งต่าง ๆ ในการใช้งานที่แตกต่างกัน รายละเอียดขึ้นอยู่กับรสชาติของ regex ที่คุณใช้ Notepad ++ มีตัวของมันเองซึ่งอาจแตกต่างจากสิ่งที่คุณเรียนรู้เล็กน้อย อย่างไรก็ตามการเรียนรู้รสชาติใด ๆ ของ regex ทำให้การทำความเข้าใจอื่น ๆ ง่ายขึ้นมาก พวกมันเหมือนกันหมด
terdon

1

สั้นหนึ่ง:

(.*)\.pdf$



ทำไมการจับภาพ / จัดกลุ่ม:

เมื่อคุณส่ง regex ไปยังโปรแกรมหรือใช้ในโปรแกรมของคุณคุณจะต้องจัดเก็บข้อมูลการแข่งขันคุณใช้การจัดกลุ่ม

จากตัวอย่าง regex ด้านบนโปรแกรมจะตรวจสอบว่า regex ตรงกันหรือไม่ถ้าใช่คุณสามารถรับวลีที่คุณแนบมาด้วย()

การสาธิต:

String stringToCheck = "example.pdf";           // Example string for testing
Pattern p = Pattern.compile("(.*)\.pdf$");      // Matching regex
Matcher m = r.matcher(stringToCheck);           // Java's own component to 'match' the string, proccessing is here
if (m.matches()) {                              // Check if the regex has matched
                                                // What? How to reterive the filename?
                                                // That's why we grouped our filename in the regex
    String filename = m.group(1);               // Reterive the first grouped part
    System.out.println(filename);               // Java's own way to print string, this is printing filename
}                                               // ??? PROFIT
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.