ตอบ
ถอนหายใจฉันใช้เวลา 45 นาทีในการหาคำตอบสำหรับคำถามง่าย ๆ นี้ คำตอบคือ:grepl(needle, haystack, fixed=TRUE)
# Correct
> grepl("1+2", "1+2", fixed=TRUE)
[1] TRUE
> grepl("1+2", "123+456", fixed=TRUE)
[1] FALSE
# Incorrect
> grepl("1+2", "1+2")
[1] FALSE
> grepl("1+2", "123+456")
[1] TRUE
การตีความ
grep
ได้รับการตั้งชื่อตามปฏิบัติการลีนุกซ์ซึ่งเป็นตัวย่อของ " G lobal R egular E xpression P rint " มันจะอ่านบรรทัดอินพุตแล้วพิมพ์พวกมันหากตรงกับอาร์กิวเมนต์ที่คุณให้ "ทั่วโลก" หมายถึงการจับคู่อาจเกิดขึ้นที่ใดก็ได้ในบรรทัดอินพุตฉันจะอธิบาย "นิพจน์ทั่วไป" ด้านล่าง แต่แนวคิดนี้เป็นวิธีที่ชาญฉลาดในการจับคู่สตริง (R เรียกอักขระนี้ว่า "" class("abc")
) และ "พิมพ์ "เพราะเป็นโปรแกรมบรรทัดคำสั่งการเปล่งเอาต์พุตหมายความว่ามันพิมพ์ไปยังสตริงเอาต์พุต
ตอนนี้grep
โปรแกรมนั้นเป็นตัวกรองจากบรรทัดอินพุตไปจนถึงบรรทัดเอาต์พุต และดูเหมือนว่าgrep
ฟังก์ชั่นของ R จะคล้ายกันกับอาร์เรย์ของอินพุต สำหรับเหตุผลที่ไม่รู้จักฉันอย่างเต็มที่ (ฉันเพิ่งเริ่มเล่นกับ R เมื่อประมาณหนึ่งชั่วโมงที่ผ่านมา) มันส่งคืนเวกเตอร์ของดัชนีที่ตรงกันแทนที่จะเป็นรายการการแข่งขัน
แต่กลับไปที่คำถามดั้งเดิมของคุณสิ่งที่เราต้องการจริงๆคือการรู้ว่าเราพบเข็มในกองหญ้าหรือไม่ เห็นได้ชัดว่าพวกเขาตัดสินใจตั้งชื่อฟังก์ชั่นนี้grepl
เช่นเดียวกับใน "grep" แต่มีค่าส่งคืน" L ogical" (พวกเขาเรียกค่าตรรกะจริงและเท็จเช่นclass(TRUE)
)
ดังนั้นตอนนี้เรารู้ว่าชื่อมาจากไหนและควรทำอย่างไร ให้กลับไปที่นิพจน์ปกติ อาร์กิวเมนต์ถึงแม้ว่าพวกเขาจะเป็นสตริงพวกเขาจะใช้ในการสร้างการแสดงออกปกติ (ต่อจากนี้ไป: regex) regex เป็นวิธีจับคู่สตริง (หากคำจำกัดความนี้ทำให้คุณหงุดหงิด ตัวอย่างเช่น regex a
จับคู่อักขระ"a"
regex a*
จับคู่อักขระ"a"
0 หรือมากกว่าและ regex a+
จะจับคู่อักขระ"a"
1 หรือมากกว่านั้น ดังนั้นในตัวอย่างด้านบนเข็มที่เรากำลังค้นหา1+2
เมื่อถือว่าเป็น regex หมายถึง "หนึ่งหรือมากกว่า 1 ตามด้วย 2" ... แต่เราตามมาด้วยเครื่องหมายบวก!
ดังนั้นหากคุณใช้การgrepl
ตั้งค่าแบบไม่มีfixed
เข็มเข็มของคุณจะเป็นกองฟางโดยไม่ตั้งใจและนั่นอาจทำงานได้ค่อนข้างบ่อยเราสามารถเห็นได้ว่ามันสามารถใช้งานได้กับตัวอย่างของ OP แต่นั่นเป็นข้อผิดพลาดแฝง! เราจำเป็นต้องบอกว่าอินพุตเป็นสตริงไม่ใช่ regex ซึ่งเห็นได้ชัดว่าfixed
มีไว้สำหรับอะไร ทำไมต้องแก้ไข ไม่มีเงื่อนงำคั่นคำตอบนี้ b / c คุณอาจต้องค้นหาอีก 5 ครั้งก่อนที่คุณจะได้รับการจดจำ
ความคิดสุดท้ายเล็กน้อย
ยิ่งรหัสของคุณดีขึ้นเท่าไหร่ประวัติที่คุณต้องรู้ก็จะยิ่งน้อยลงเท่านั้น ทุกอาร์กิวเมนต์สามารถมีค่าที่น่าสนใจอย่างน้อยสองค่า (ไม่เช่นนั้นจะไม่จำเป็นต้องเป็นอาร์กิวเมนต์) เอกสารรายการ 9 ข้อโต้แย้งที่นี่ซึ่งหมายความว่ามีอย่างน้อย 2 ^ 9 = 512 วิธีในการเรียกใช้นั่นเป็นงานที่ต้องทำมากมาย เขียนทดสอบและจำไว้ว่า ... แยกฟังก์ชั่นดังกล่าวออก (แยกออก, ลบการพึ่งพาซึ่งกันและกัน, สิ่งสตริงจะแตกต่างจากสิ่งที่ regex แตกต่างจากสิ่งเวกเตอร์) ตัวเลือกบางตัวนั้นไม่เหมือนกันไม่ให้ผู้ใช้วิธีที่ไม่ถูกต้องในการใช้รหัสเช่นการเรียกใช้ที่มีปัญหาควรเป็นแบบไร้โครงสร้าง (เช่นผ่านตัวเลือกที่ไม่มีอยู่) ไม่ใช่แบบไร้เหตุผล (ซึ่งคุณต้อง ปล่อยคำเตือนเพื่ออธิบาย) ใส่คำเปรียบเทียบ: การแทนที่ประตูหน้าในด้านข้างของชั้น 10 ด้วยผนังจะดีกว่าการแขวนป้ายที่เตือนการใช้งาน แต่ดีกว่าอย่างใดอย่างหนึ่ง ในอินเทอร์เฟซฟังก์ชันจะกำหนดสิ่งที่อาร์กิวเมนต์ควรมีลักษณะไม่ใช่ตัวเรียก (เนื่องจากผู้เรียกใช้ขึ้นอยู่กับฟังก์ชันโดยอนุมานทุกสิ่งที่ทุกคนอาจต้องการเรียกด้วยทำให้ฟังก์ชันนั้นขึ้นอยู่กับผู้โทรด้วยเช่นกันและประเภทนี้ การขึ้นต่อกันของวัฏจักรจะทำให้ระบบเกิดการอุดตันอย่างรวดเร็วและไม่ให้ผลประโยชน์ที่คุณคาดหวัง) ระวังประเภทที่ทำให้สับสนมันเป็นข้อบกพร่องในการออกแบบที่เป็นเช่นนั้น อนุมานทุกสิ่งที่ทุกคนอาจต้องการเรียกใช้ด้วยทำให้ฟังก์ชั่นนั้นขึ้นอยู่กับผู้โทรเช่นกันและการพึ่งพาวงจรประเภทนี้จะขัดขวางระบบอย่างรวดเร็วและไม่ให้ประโยชน์ที่คุณคาดหวัง) ระวังประเภทที่ทำให้สับสนมันเป็นข้อบกพร่องในการออกแบบที่เป็นเช่นนั้น อนุมานทุกสิ่งที่ทุกคนอาจต้องการเรียกใช้ด้วยทำให้ฟังก์ชั่นนั้นขึ้นอยู่กับผู้โทรเช่นกันและการพึ่งพาวงจรประเภทนี้จะขัดขวางระบบอย่างรวดเร็วและไม่ให้ประโยชน์ที่คุณคาดหวัง) ระวังประเภทที่ทำให้สับสนมันเป็นข้อบกพร่องในการออกแบบที่เป็นเช่นนั้นTRUE
และ0
และ"abc"
เวกเตอร์ทั้งหมด
fixed=TRUE
มิฉะนั้นคุณจะถือว่าเป็น regex แทนที่จะเป็นสตริง ดูคำตอบของฉันตั้งแต่ตุลาคม 2559