Pembatas tidak boleh alfanumerik atau garis miring terbalik dan preg_match

88

Saya memiliki kode ini:

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

dan ketika saya menjalankannya mengembalikan kesalahan ini:

Peringatan: preg_match () [function.preg-match]: Pembatas tidak boleh alfanumerik atau garis miring terbalik

pengguna547363
sumber
2
Sebagai catatan yang mungkin berguna bagi orang lain, jika Anda meneruskan semua argumen Anda preg_match()sebagai variabel, pastikan Anda tidak mendapatkan urutan variabel yang secara tidak sengaja tercampur dalam pemanggilan fungsi karena ini juga hampir pasti akan menghasilkan hal yang sama. kesalahan muncul.
bluebinary
1
Anda memerlukan pembatas dalam string regexp Anda
Ki Jéy
2
Gunakan$pattern = "/My name is '(.*)' and im fine/";
gk.

Jawaban:

134

Anda membutuhkan pembatas untuk pola Anda. Ini harus ditambahkan di awal dan akhir pola seperti:

$pattern = "/My name is '(.*)' and im fine/";  // With / as a delimeter 
Paul
sumber
1
Berhati-hatilah menggunakan tanda kutip ganda untuk membungkus ekspresi regex, jika tidak, beberapa kombinasi karakter \ + (seperti \luntuk umpan baris) akan diubah menjadi karakternya, yang mungkin menghasilkan ekspresi selain yang diharapkan. Gunakan tanda kutip tunggal. Lihat deskripsi String php .
Patanjali
Dalam contoh ini, string menyertakan tanda kutip tunggal sehingga lebih mudah menggunakan tanda kutip ganda untuk mengapitnya (menghindari pelolosan \'yang diperlukan jika diapit dalam tanda kutip tunggal).
Paul
Saya membuat komentar umum, karena orang yang melihat contoh mungkin menganggapnya sebagai sesuatu yang 'dipotong kue' untuk diri mereka sendiri, tidak menyadari konsekuensi tak terduga yang mungkin terjadi jika mereka memperluasnya ke situasi lain. Sayangnya, saya tidak dapat mengubah komentar saya menjadi lebih spesifik.
Patanjali
68

Solusinya (yang tidak disebutkan oleh jawaban lain — setidaknya pada saat saya pertama kali menulis ini) adalah bahwa ketika PHP mengacu pada pembatas, itu tidak mengacu pada pembatas yang Anda lihat di kode Anda (yang merupakan tanda kutip) tetapi berikutnya karakter di dalam string. (Sebenarnya saya belum pernah melihat ini dinyatakan di mana pun dalam dokumentasi apa pun: Anda harus melihatnya dalam contoh.) Jadi, alih-alih memiliki sintaks ekspresi reguler seperti yang mungkin biasa Anda lakukan dari banyak bahasa lain:

/something/

PHP menggunakan string, dan kemudian melihat ke dalam string untuk pembatas lain :

'/something/'

Pembatas yang dimaksud PHP adalah pasangan /karakter, bukan pasangan 'karakter. Jadi jika Anda menulis 'something', PHP akan mengambil spembatas yang dimaksudkan dan mengeluh bahwa Anda tidak diizinkan menggunakan karakter alfanumerik sebagai pembatas Anda.

Jadi, jika Anda ingin meneruskan (misalnya) iuntuk menunjukkan bahwa Anda menginginkan kecocokan case-insensitve, Anda meneruskannya di dalam string tetapi di luar pembatas regex:

'/something/i'

Jika Anda ingin menggunakan sesuatu selain /sebagai pembatas, Anda bisa, seperti jika Anda mencocokkan URL dan tidak ingin keluar dari semua garis miring:

'~something~'
iconoclast
sumber
1
@Gruber: terima kasih! Anda selalu dapat mengirim semua teman Anda tautan ke sana dan biarkan mereka memberi suara positif;)
iconoclast
1
Menjelaskan dokumentasi apa yang tidak menjelaskan .. +1 Terima kasih!
Ju Oliveira
Jawaban yang mendapat suara positif tertinggi adalah sama dengan ini, namun, saya bersyukur sekarang mengerti mengapa ini adalah jawaban yang benar. +1 Terima kasih!
Eklektik
21

Anda harus menentukan pembatas untuk ekspresi Anda. Pembatas adalah karakter khusus yang digunakan di awal dan akhir ekspresi Anda untuk menunjukkan bagian mana yang merupakan ekspresi. Ini memungkinkan Anda untuk menggunakan pengubah dan penerjemah untuk mengetahui mana yang merupakan ekspresi dan mana yang merupakan pengubah. Seperti yang dinyatakan dalam pesan kesalahan, pembatas tidak boleh menjadi garis miring terbalik karena garis miring terbalik adalah karakter pelolos.

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

dan di bawah contoh yang sama tetapi dengan ipengubah untuk mencocokkan tanpa peka huruf kapital.

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

Seperti yang Anda lihat, bagian iluar garis miring dan oleh karena itu diartikan sebagai pengubah.

Perhatikan juga bahwa jika Anda menggunakan karakter garis miring ke depan (/) sebagai pemisah, Anda harus keluar dari penggunaan lebih lanjut dari / dalam ekspresi reguler, jika ada.

Ben Swinburne
sumber
7

Pola harus memiliki pembatas. Pembatas dapat berupa garis miring (/) atau karakter non alfanumerik (#, $, *, ...). Contoh

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

Anda juga dapat menggunakan pustaka T-Regx yang memiliki pembatas otomatis untuk Anda:

$matches = pattern("My name is '(.*)' and im fine")->match($string1)->all();

                 // ↑ No delimiters needed 
Danon
sumber
0

Mungkin tidak terkait dengan contoh kode asli, tetapi saya menerima kesalahan "Pembatas tidak boleh alfanumerik atau garis miring terbalik" dan di-Google di sini. Alasan: Saya mencampur urutan parameter untuk preg_match. Pola adalah parameter kedua dan string yang cocok adalah yang pertama. Hati-hati :)

Nubian
sumber
-2

Silakan coba dengan ini

 $pattern = "/My name is '\(.*\)' and im fine/"; 
Vikas Naranje
sumber
Mengapa menghindari tanda kurung?
Ki Jéy
1
@tokopedia Dalam situasi OP, mereka ingin mengekstrak nama, jadi tanda kurung diperlukan untuk pertandingan, dan oleh karena itu TIDAK boleh di-escape. Inilah mengapa saya merendahkannya.
Patanjali