Bagaimana cara menghapus karakter non-alfanumerik?

349

Saya perlu menghapus semua karakter dari string yang tidak a-z A-Z 0-9diatur atau bukan spasi.

Apakah ada yang punya fungsi untuk melakukan ini?

zuk1
sumber

Jawaban:

695

Sepertinya Anda hampir tahu apa yang ingin Anda lakukan, pada dasarnya Anda mendefinisikannya sebagai regex.

preg_replace("/[^A-Za-z0-9 ]/", '', $string);
Chad Birch
sumber
8
zuk1: regexbuddy sangat membantu dengan itu
relipse
2
Berikut ini contoh jika Anda ingin memasukkan tanda hubung sebagai karakter yang diizinkan. Saya memerlukan ini karena saya harus menghapus karakter yang tidak diizinkan dari nama pengguna Moodle, berdasarkan alamat email: preg_replace ("/ [^ a-z0-9 _. @ \ -] /", '', $ string);
Evan Donovan
2
Apakah ini bekerja persis sama dengan tanda kutip (tanda kutip tunggal) di sekitar ekspresi reguler, alih-alih tanda kutip (tanda kutip ganda)? Misalnya:preg_replace('/[^A-Za-z0-9 ]/', '', $string);
2540625
3
Kami ingin penjelasan tentang ini :). Orang-orang datang ke sini untuk melihat Mengapa demikian adanya. Silakan pertimbangkan penjelasan Regex juga! Terima kasih
Pratik
1
Bagaimana jika kita ingin mempertahankan karakter yang ditekankan?
wonzbak
169

Untuk karakter unicode, itu adalah:

preg_replace("/[^[:alnum:][:space:]]/u", '', $string);
voondo
sumber
hai voondo, ada apa dengan hal / ui .. apa namanya? adakah yang bisa menjelaskan padaku. Terima kasih.
kebyang
4
Untuk klarifikasi, mereka disebut bendera. Mereka diletakkan setelah pembatas penutup (dalam hal ini "/", tapi bisa "~" atau "@" atau karakter apa pun yang ingin Anda gunakan selama pembatas pembukaan dan penutupan adalah sama) dan ubah perilaku ekspresi.
Doktor J
1
Btw, \wsertakan \ddan karenanya \dtidak perlu. Juga, ini salah karena juga akan meninggalkan garis bawah pada string yang dihasilkan (yang juga termasuk dalam \w).
smathy
2
Masih ada kesalahan dalam hal ini, kelas karakter harus diakhiri dengan ':]' sehingga baris yang benar adalah: preg_replace ("/ [^ [: alnum:] [: space:]] / ui", '', $ string);
h00ligan
4
Apakah ibendera benar-benar diperlukan di sini karena [:alnum:]sudah mencakup kedua kasus?
billynoah
50

Ekspresi reguler adalah jawaban Anda.

$str = preg_replace('/[^a-z\d ]/i', '', $str);
  • The isingkatan kasus sensitif.
  • ^ berarti, tidak dimulai dengan.
  • \d cocok dengan angka apa pun.
  • a-zcocok dengan semua karakter antara adan z. Karena iparameter Anda tidak perlu menentukan a-zdan A-Z.
  • Setelah \dada spasi, maka spasi diizinkan di regex ini.
raspi
sumber
3
Kami ingin penjelasan tentang ini :). Orang-orang datang ke sini untuk melihat Mengapa demikian adanya. Silakan pertimbangkan penjelasan Regex juga! Tidak semua orang cukup tahu apa yang Anda tulis di sana tanpa penjelasan. Terima kasih
Pratik
@PratikCJoshi Saya singkatan dari case sensitive. ^ Berarti, tidak dimulai dengan. cocok dengan digit apa pun. az cocok dengan semua karakter antara a dan z. Karena parameter i Anda tidak perlu menentukan az dan AZ. Setelah ada spasi, maka spasi diizinkan di regex ini.
Bart
1
Orang tidak membaca komentar sebagai jawaban. Perbarui jawaban!
Pratik
18

inilah regex yang sangat sederhana untuk itu:

\W|_

dan digunakan sesuai kebutuhan (dengan /pembatas slash maju ).

preg_replace("/\W|_/", '', $string);

Uji di sini dengan alat hebat ini yang menjelaskan apa yang dilakukan regex:

http://www.regexr.com/

Alex Stephens
sumber
1
Anda masih memerlukan /ubendera jika tidak, huruf non-ascii juga dihapus.
Xeoncross
Rapi tetapi juga akan cocok dengan spasi dan jika ini diinginkan, mungkin bisa menggandakan kinerja dengan menggunakan kelas karakter dan quantifier tambahan untuk satu atau lebih [\W_]+
gelembung bobble
18

Jika Anda perlu mendukung bahasa lain, alih-alih AZ biasa, Anda dapat menggunakan yang berikut:

preg_replace('/[^\p{L}\p{N} ]+/', '', $string);
  • [^\p{L}\p{N} ]mendefinisikan negated (Ini akan cocok dengan karakter yang tidak didefinisikan) kelas karakter dari:
    • \p{L}: surat dari bahasa apa pun .
    • \p{N}: karakter numerik dalam skrip apa pun .
    • : karakter spasi.
  • + rakus cocok dengan kelas karakter antara 1 dan kali tidak terbatas .

Ini akan mempertahankan huruf dan angka dari bahasa dan skrip lain serta AZ:

preg_replace('/[^\p{L}\p{N} ]+/', '', 'hello-world'); // helloworld
preg_replace('/[^\p{L}\p{N} ]+/', '', 'abc@~#123-+=öäå'); // abc123öäå
preg_replace('/[^\p{L}\p{N} ]+/', '', '你好世界!@£$%^&*()'); // 你好世界

Catatan: Ini adalah pertanyaan yang sangat lama, namun masih relevan. Saya menjawab murni untuk memberikan informasi tambahan yang mungkin berguna bagi pengunjung masa depan.

Jonathon
sumber
8
[\W_]+

 

$string = preg_replace("/[\W_]+/u", '', $string);

Itu memilih semua bukan AZ, az, 0-9 dan menghapusnya.

Lihat contoh di sini: https://regexr.com/3h1rj

Intacto
sumber
1
apa arti regex / [\ W _] + / u ini?
Ângelo Rigo
\Wadalah kebalikan dari \wkarakter A-Za-z0-9_. Jadi \Wakan cocok dengan karakter apa pun yang bukan A-Za-z0-9_dan menghapusnya. Ini []adalah batas karakter yang ditetapkan . Ini +berlebihan pada batas karakter yang ditetapkan tetapi biasanya berarti 1 atau lebih karakter. The ubendera memperluas ekspresi untuk menyertakan dukungan karakter unicode, yang berarti tidak akan menghapus karakter di luar karakter kode 255 seperti ª²³µ. Contoh berbagai penggunaan 3v4l.org/hSVV5 dengan karakter unicode dan ascii.
fyrye
2
preg_replace("/\W+/", '', $string)

Anda dapat mengujinya di sini: http://regexr.com/

TERLALU
sumber
Per @Alex Stevens menjawab, ini tidak menangkap garis bawah "_".
Ariel Allon
0

Saya juga mencari jawabannya dan niat saya adalah untuk membersihkan setiap non-alpha dan seharusnya tidak ada lebih dari satu ruang.
Jadi, saya mengubah jawaban Alex untuk ini, dan ini berfungsi untuk saya preg_replace('/[^a-z|\s+]+/i', ' ', $name)
. Regex di atas beralih sy8ed sirajul7_islamke sy ed sirajul islam
Penjelasan: regex akan memeriksa TIDAK SETIAP dari a ke z jika tidak sensitif atau lebih dari satu spasi, dan akan dikonversi menjadi satu ruang.

ssi-anik
sumber
-2

Anda dapat membagi string menjadi karakter dan memfilternya.

<?php 

function filter_alphanum($string) {
    $characters = str_split($string);
    $alphaNumeric = array_filter($characters,"ctype_alnum");
    return join($alphaNumeric);
}

$res = filter_alphanum("a!bc!#123");
print_r($res); // abc123

?>
zekel
sumber
Alasan downvote: 3v4l.org/fqLVZ Lebih lanjut memanggil fungsi (3 + N) pada string dengan panjang yang tidak diketahui tampaknya benar-benar tidak menarik dibandingkan dengan panggilan tunggal dan sederhana preg_replace().
mickmackusa