Bagaimana saya bisa mengubah ekspresi ereg ke preg di PHP?

140

Karena ekspresi reguler POSIX (ereg) sudah tidak digunakan lagi sejak PHP 5.3.0, saya ingin tahu cara mudah untuk mengubah ekspresi lama menjadi PCRE (Perl Compatible Regular Expressions) (preg) .

Sebagai contoh, saya memiliki ungkapan reguler ini:

eregi('^hello world');

Bagaimana saya bisa menerjemahkan ekspresi menjadi preg_matchekspresi yang kompatibel?

Catatan: Posting ini berfungsi sebagai pengganti untuk semua pos yang terkait dengan konversi dari ereg ke preg, dan sebagai opsi duplikat untuk pertanyaan terkait. Tolong jangan tutup pertanyaan ini.

Terkait:

netcoder
sumber
2
@ yes123: Ya, itu intinya, saya juga bosan. Saya ingin posting wiki yang benar-benar menjelaskan sesuatu sehingga kami dapat menutup semua pertanyaan individual ini.
netcoder
Saya pikir tidak perlu untuk ini karena Anda hanya perlu membungkus yang lama dengan pembatas. Juga saya pikir Anda bisa menggunakan pertanyaan yang dijawab sebelumnya untuk ini.
dinamis
Ah, memilih untuk ditutup sebelum membaca komentar. Sebagai pengganti, itu dapat melayani tujuan, tetapi bukankah ada pertanyaan lain yang lebih tua yang bisa berfungsi seperti itu?
Wrikken
Hmm, memang. ereg [php]tidak menghasilkan hasil yang sangat berguna. Oke, bisa berikan dukungan saya untuk yang satu ini.
Wrikken
8
Teman-teman, sepertinya kita hampir membuat lingkaran pertanyaan tertutup tentang topik ini semua saling menunjuk satu sama lain. Pada tingkat ini mereka semua akan ditutup :)
Kev

Jawaban:

142

Perubahan terbesar dalam sintaks adalah penambahan pembatas .

ereg('^hello', $str);
preg_match('/^hello/', $str);

Pembatas bisa berupa apa saja yang bukan alpha-numeric, backslash, atau karakter whitespace. Yang paling banyak digunakan umumnya ~, /dan #.

Anda juga dapat menggunakan tanda kurung yang cocok:

preg_match('[^hello]', $str);
preg_match('(^hello)', $str);
preg_match('{^hello}', $str);
// etc

Jika pembatas Anda ditemukan dalam ekspresi reguler, Anda harus menghindarinya:

ereg('^/hello', $str);
preg_match('/^\/hello/', $str);

Anda dapat dengan mudah keluar dari semua pembatas dan karakter yang dipesan dalam string dengan menggunakan preg_quote :

$expr = preg_quote('/hello', '/');
preg_match('/^'.$expr.'/', $str);

Juga, PCRE mendukung pengubah untuk berbagai hal. Salah satu yang paling banyak digunakan adalah pengubah case-insensitive i, alternatif untuk eregi :

eregi('^hello', 'HELLO');
preg_match('/^hello/i', 'HELLO');

Anda dapat menemukan referensi lengkap untuk sintaks PCRE dalam PHP di manual , serta daftar perbedaan antara POSIX regex dan PCRE untuk membantu mengubah ekspresi.

Namun, dalam contoh sederhana Anda, Anda tidak akan menggunakan ekspresi reguler:

stripos($str, 'hello world') === 0
netcoder
sumber
2
Penjelasan luar biasa! Saya ingin menambahkan kasus khusus di mana Anda mengkonversi dari ereg ke preg_match dan Anda hanya perlu melarikan diri dari pembatas dan karakter yang tidak dipesan (karena mereka sudah berfungsi sebagai karakter khusus, kami tidak ingin melarikan diri dari mereka) : preg_match ('/'. str_replace ('/', '\ /', $ expr). '/', $ str);
Lolito
Ini sangat berharga untuk dicatat bahwa jika Anda menggunakan tanda kurung yang cocok, maka Anda tidak perlu melarikan diri karakter "hanya karena itu sama dengan pembatas" seperti yang Anda lakukan dengan simbol lain seperti /^\/hello/contoh. (a(b)c)adalah PCRE yang benar-benar valid dan dibatasi. Saya pribadi suka menggunakan tanda kurung ()untuk mengingatkan diri saya bahwa pertandingan yang ditangkap pertama adalah segalanya.
Niet the Dark Absol
Dapatkah saya mengatakan, saya sangat benci PHP! (.. Hanya saja ada lagi) saya harus mencari jawaban ini ketika shared hosting web server saya akan diperbarui ke versi baru dan error_logs mendapatkan penuh dengan peringatan ini: PHP Deprecated: Function ereg() is deprecated in.... Argh!
c00000fd
bagaimana cara mengubahnya? $ regex = $ e. '((\. [^ \.'. $ e. '] [^'. $ e. '] *) | (\. \. [^'. $ e. '] +) | ([^ \. ] [^ '. $ e.'] *)) '. $ e. '\. \.' . $ e; untuk preg_math itu bekerja doest hanya dengan menambahkan / modifier /
bdalina
32

Penggantian Ereg dengan preg (pada PHP 5.3.0) adalah langkah yang tepat untuk kami.

preg_match, yang menggunakan sintaks ekspresi reguler yang kompatibel dengan Perl, seringkali merupakan alternatif yang lebih cepat untuk ereg.

Anda harus mengetahui 4 hal utama untuk mem-porting pola-pola prioritas:

  1. Tambahkan pembatas (/):'pattern' => '/pattern/'

  2. Pembatas pembatas jika itu adalah bagian dari pola: 'patt/ern' => '/patt\/ern/'
    Mencapai secara terprogram dengan cara berikut:
    $old_pattern = '<div>.+</div>';
    $new_pattern = '/' . addcslashes($old_pattern, '/') . '/';

  3. eregi (case-insensitive matching): 'pattern' => '/pattern/i' Jadi, jika Anda menggunakan fungsi eregi untuk case-insenstive matching, tambahkan saja 'i' di akhir pola baru ('/ pattern /').

  4. Nilai ASCII : Dalam kesalahan, jika Anda menggunakan angka dalam pola, diasumsikan bahwa Anda mengacu pada ASCII karakter. Namun dalam preg, angka tidak diperlakukan sebagai nilai ASCII. Jadi, jika pola Anda mengandung nilai ASCII dalam ekspresi ereg (misalnya: baris baru, tab, dll.), Lalu konversikan ke hexadecimal dan awali dengan \ x.
    Example: 9(tab) becomes \x9 or alternatively use \t.

Sumoanand
sumber
8

Dari PHP versi 5.3, eregsudah usang.

Pindah dari eregke preg_matchhanya perubahan kecil dalam pola kita.

Pertama, Anda harus menambahkan pembatas ke kode Anda, misalnya:

ereg('A-Z0-9a-z', 'string');

untuk

preg_match('/A-Z0-9a-z/', 'string');

Untuk eregipencocokan case-insensitive, letakkan isetelah pembatas terakhir, misalnya:

eregi('pattern', 'string');

untuk

preg_match ('/pattern/i', 'string');
Narayan
sumber
7

Ada lebih banyak perbedaan antara ereg()dan preg_replace()bukan hanya sintaks:

  • Nilai pengembalian:

    • Pada kesalahan : keduanya kembaliFALSE
    • Pada tidak cocok : ereg()kembali FALSE, preg_match()kembali0
    • Sesuai : ereg()mengembalikan panjang string atau 1, preg_match()mengembalikan selalu1
  • Array yang dihasilkan dari substring yang cocok: Jika beberapa substring tidak ditemukan sama sekali ( (b)dalam ...a(b)?), item yang sesuai dalam ereg()hasilnya akan FALSE, sedangkan di preg_match()dalamnya tidak akan diatur sama sekali.

Jika seseorang tidak cukup berani untuk mengubah ereg()ke preg_match(), dia dapat menggunakan mb_ereg () , yang masih tersedia di PHP 7.

Roman Hocke
sumber