ตัวคั่นต้องไม่เป็นตัวอักษรและตัวเลขคละกันหรือแบ็กสแลชและ preg_match


88

ฉันมีรหัสนี้:

$string1 = "My name is 'Kate' and im fine"; 
$pattern = "My name is '(.*)' and im fine"; 
preg_match($pattern , $string1, $matches);
echo $matches[1];

และเมื่อฉันเรียกใช้มันจะส่งกลับข้อผิดพลาดนี้:

คำเตือน: preg_match () [function.preg-match]: ตัวคั่นต้องไม่ใช่ตัวอักษรและตัวเลขหรือเครื่องหมายแบ็กสแลช


2
ในฐานะที่เป็นหมายเหตุที่อาจเป็นประโยชน์กับผู้อื่นหากคุณส่งอาร์กิวเมนต์ทั้งหมดของคุณไปpreg_match()เป็นตัวแปรตรวจสอบให้แน่ใจว่าคุณไม่ได้รับคำสั่งของตัวแปรที่ผสมกันโดยไม่ได้ตั้งใจในการเรียกฟังก์ชันเนื่องจากสิ่งนี้จะส่งผลให้เกิดสิ่งเดียวกัน ปรากฏข้อผิดพลาด
bluebinary

1
คุณต้องมีตัวคั่นในสตริง regexp ของคุณ
Ki Jéy

2
ใช้$pattern = "/My name is '(.*)' and im fine/";
gk.

คำตอบ:


134

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

$pattern = "/My name is '(.*)' and im fine/";  // With / as a delimeter 

1
ระวังการใช้เครื่องหมายคำพูดคู่เพื่อห่อหุ้มนิพจน์ regex มิฉะนั้นชุดอักขระ \ + บางตัว (เช่น\lสำหรับฟีดบรรทัด) จะถูกแปลงเป็นอักขระซึ่งอาจทำให้เกิดนิพจน์อื่นที่ไม่ใช่ที่คาดไว้ ใช้เครื่องหมายคำพูดเดี่ยว ดูรายละเอียด PHP สตริง
Patanjali

ในตัวอย่างนี้สตริงจะมีเครื่องหมายคำพูดเดี่ยวดังนั้นจึงง่ายกว่าที่จะใช้เครื่องหมายคำพูดคู่เพื่อใส่เครื่องหมายคำพูด (หลีกเลี่ยงการหลีกเลี่ยง\'ที่จะต้องใช้หากอยู่ในเครื่องหมายคำพูดเดี่ยว)
พอล

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

68

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

/something/

PHP ใช้สตริงจากนั้นดูภายในสตริงเพื่อหาตัวคั่นอื่น :

'/something/'

PHP ตัวคั่นหมายถึงคู่ของ/อักขระแทนที่จะเป็นคู่ของ'อักขระ ดังนั้นถ้าคุณเขียน'something'PHP จะใช้sเป็นตัวคั่นที่ตั้งใจไว้และบ่นว่าคุณไม่ได้รับอนุญาตให้ใช้อักขระที่เป็นตัวอักษรและตัวเลขเป็นตัวคั่นของคุณ

ดังนั้นหากคุณต้องการส่งผ่าน (เช่น) iเพื่อแสดงว่าคุณต้องการการจับคู่แบบไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่คุณจะส่งผ่านภายในสตริง แต่อยู่นอกตัวคั่น regex:

'/something/i'

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

'~something~'

1
@ กรูเบอร์: ขอบคุณ! คุณสามารถส่งลิงค์เพื่อนของคุณไปที่ลิงค์นี้และให้พวกเขาโหวตได้ตลอดเวลา;)
iconoclast

1
อธิบายเอกสารอะไรไม่ได้อธิบาย .. +1 ขอบคุณ!
Ju Oliveira

คำตอบที่ได้รับการโหวตสูงสุดคือคำตอบเดียวกันอย่างไรก็ตามตอนนี้ฉันรู้สึกขอบคุณที่เข้าใจว่าทำไมจึงเป็นคำตอบที่ถูกต้อง +1 ขอบคุณ!
ผสมผสาน

21

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

$pattern = "/My name is '(.*)' and im fine/";

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

$pattern = "/My name is '(.*)' and im fine/i";

อย่างที่คุณเห็นไฟล์ iอยู่ด้านนอกของเครื่องหมายทับดังนั้นจึงถูกตีความว่าเป็นตัวปรับแต่ง

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


7

รูปแบบต้องมีตัวคั่น ตัวคั่นอาจเป็นเครื่องหมายทับ (/) หรืออักขระที่ไม่ใช่ตัวเลขและตัวอักษร (#, $, *, ... ) ตัวอย่าง

$pattern = "/My name is '(.*)' and im fine/"; 
$pattern = "#My name is '(.*)' and im fine#";
$pattern = "@My name is '(.*)' and im fine@";  


0

อาจไม่เกี่ยวข้องกับตัวอย่างโค้ดต้นฉบับ แต่ฉันได้รับข้อผิดพลาด "ตัวคั่นต้องไม่ใช่ตัวอักษรและตัวเลขคละกันหรือแบ็กสแลช" และ Googled ที่นี่ เหตุผล: ฉันผสมลำดับพารามิเตอร์สำหรับ preg_match Pattern เป็นพารามิเตอร์ที่สองและสตริงที่จับคู่เป็นอันดับแรก ระวัง :)


-2

โปรดลองด้วยสิ่งนี้

 $pattern = "/My name is '\(.*\)' and im fine/"; 

ทำไมต้องหนีวงเล็บ
Ki Jéy

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