Dấu phân cách không được là chữ và số hoặc dấu gạch chéo ngược và preg_match


86

Tôi có mã này:

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

và khi tôi chạy nó trả về lỗi này:

Cảnh báo: preg_match () [function.preg-match]: Dấu phân cách không được là chữ và số hoặc dấu gạch chéo ngược


2
Một lưu ý có thể hữu ích cho những người khác, nếu bạn đang chuyển tất cả các đối số của mình preg_match()dưới dạng biến, hãy đảm bảo rằng bạn không nhận được thứ tự của các biến vô tình bị trộn lẫn trong lệnh gọi hàm vì điều này cũng gần như chắc chắn sẽ dẫn đến kết quả tương tự lỗi xuất hiện.
bluebinary

1
Bạn cần một dấu phân cách trong chuỗi regexp của bạn
Ki Jey

2
Sử dụng$pattern = "/My name is '(.*)' and im fine/";
gk.

Câu trả lời:


133

Bạn cần một dấu phân cách cho mẫu của bạn. Nó nên được thêm vào đầu và cuối của mẫu như sau:

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

Hãy cẩn thận khi sử dụng dấu ngoặc kép để mã hóa biểu thức regex, nếu không, một số tổ hợp ký tự \ + (chẳng hạn như \lđối với nguồn cấp dữ liệu dòng) sẽ được chuyển đổi thành ký tự của chúng, điều này có thể tạo ra một biểu thức khác với mong đợi. Sử dụng dấu ngoặc kép. Xem mô tả chuỗi php .
Patanjali

Trong ví dụ này, chuỗi bao gồm các dấu ngoặc kép đơn, do đó, việc sử dụng dấu ngoặc kép để bao quanh nó sẽ dễ dàng hơn (tránh việc thoát ra \'sẽ được yêu cầu nếu nó được đặt trong dấu ngoặc đơn).
Paul

Tôi đang đưa ra một nhận xét chung, vì mọi người xem các ví dụ có thể coi chúng như một thứ gì đó để 'cắt cookie' cho chính họ, không nhận ra những hậu quả không lường trước được có thể xảy ra nếu họ mở rộng nó sang các tình huống khác. Rất tiếc, tôi không thể thay đổi nhận xét của mình để cụ thể hơn.
Patanjali

68

Giải pháp (mà các câu trả lời khác không đề cập đến — ít nhất là tại thời điểm tôi viết bài này) là khi PHP đề cập đến các dấu phân cách, nó không đề cập đến các dấu phân cách bạn thấy trong mã của mình (đó là các dấu ngoặc kép) mà là ký tự bên trong chuỗi. (Thực tế là tôi chưa bao giờ thấy điều này được nêu ở bất kỳ đâu trong bất kỳ tài liệu nào: bạn phải xem nó trong các ví dụ.) Vì vậy, thay vì có cú pháp biểu thức chính quy như những gì bạn có thể quen với từ nhiều ngôn ngữ khác:

/something/

PHP sử dụng chuỗi, sau đó tìm bên trong chuỗi để tìm dấu phân cách khác :

'/something/'

Dấu phân tách mà PHP đang đề cập đến là cặp /ký tự, thay vì cặp 'ký tự. Vì vậy, nếu bạn viết 'something', PHP sẽ lấy slàm dấu phân cách dự định và phàn nàn rằng bạn không được phép sử dụng các ký tự chữ và số làm dấu phân cách.

Vì vậy, nếu bạn muốn chuyển (ví dụ) một iđể cho thấy rằng bạn muốn đối sánh không phân biệt chữ hoa chữ thường, bạn chuyển nó vào bên trong chuỗi nhưng bên ngoài các dấu phân cách regex:

'/something/i'

Nếu bạn muốn sử dụng thứ gì đó khác ngoài /làm dấu phân tách, bạn có thể, chẳng hạn như nếu bạn đang khớp một URL và không muốn phải thoát khỏi tất cả các dấu gạch chéo:

'~something~'

1
@Gruber: cảm ơn! bạn luôn có thể gửi tất cả bạn bè của bạn liên kết đến nó và để họ upvote nó;)
đả phá tín ngưỡng

1
Giải thích những gì tài liệu không giải thích .. +1 Cảm ơn bạn!
Ju Oliveira

Câu trả lời được ủng hộ cao nhất cũng giống như câu trả lời này, tuy nhiên, tôi rất biết ơn vì giờ đây tôi đã hiểu tại sao đây là câu trả lời chính xác. +1 Cảm ơn!
Eclectic

21

Bạn phải chỉ định dấu phân cách cho biểu thức của mình. Dấu phân tách là một ký tự đặc biệt được sử dụng ở đầu và cuối biểu thức của bạn để biểu thị phần nào là biểu thức. Điều này cho phép bạn sử dụng các bổ ngữ và trình thông dịch để biết đâu là biểu thức và đâu là bổ ngữ. Như thông báo lỗi nêu rõ, dấu phân tách không thể là dấu gạch chéo ngược vì dấu gạch chéo ngược là ký tự thoát.

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

và bên dưới cùng một ví dụ nhưng với công cụ isửa đổi để khớp mà không phân biệt chữ hoa chữ thường.

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

Như bạn có thể thấy, phần ibên ngoài của dấu gạch chéo và do đó được hiểu là một bổ ngữ.

Cũng nên nhớ rằng nếu bạn sử dụng ký tự gạch chéo lên (/) làm dấu phân cách thì bạn phải thoát khỏi việc sử dụng thêm / trong biểu thức chính quy, nếu có.


7

Mẫu phải có dấu phân cách. Dấu phân cách có thể là một dấu gạch chéo (/) hoặc bất kỳ ký tự không phải chữ và số (#, $, *, ...). Ví dụ

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


0

Có thể không liên quan đến ví dụ mã gốc, nhưng tôi đã nhận được lỗi "Dấu phân cách không được là chữ và số hoặc dấu gạch chéo ngược" và Googled ở đây. Lý do: Tôi đã trộn thứ tự các tham số cho preg_match. Mẫu là tham số thứ hai và chuỗi cần đối sánh là tham số đầu tiên. Hãy cẩn thận :)


-2

Hãy thử với cái này

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

Tại sao lại thoát khỏi dấu ngoặc đơn?
Ki Jéy

1
@kiJey. Trong tình huống của OP, họ muốn trích xuất tên, vì vậy dấu ngoặc đơn là bắt buộc đối với trận đấu, và do đó KHÔNG được thoát. Đây là lý do tại sao tôi không thích nó.
Patanjali
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.