Ganti semua karakter non Alpha Numeric, New Lines, dan beberapa White Space dengan satu Space

136

Saya mencari solusi RegEx yang rapi untuk diganti

  • Semua Karakter non-Alpha-Numeric
  • Semua Baris Baru
  • Semua beberapa contoh ruang putih

Dengan satu ruang


Bagi mereka yang bermain di rumah ( yang berikut ini tidak bekerja )

text.replace(/[^a-z0-9]/gmi, " ").replace(/\s+/g, " ");

Pemikiran saya adalah RegEx mungkin cukup kuat untuk mencapai ini dalam satu pernyataan. Komponen yang saya pikir perlu id adalah

  • [^a-z0-9] - untuk menghapus karakter non-Alpha-Numeric
  • \s+ - Cocok dengan koleksi ruang apa pun
  • \r?\n|\r - cocok dengan semua baris baru
  • /gmi - global, multi-line, tidak sensitif huruf

Namun, sepertinya saya tidak bisa mengatur regex dengan cara yang benar ( berikut ini tidak berfungsi )

text.replace(/[^a-z0-9]|\s+|\r?\n|\r/gmi, " ");


Memasukkan

234&^%,Me,2 2013 1080p x264 5 1 BluRay
S01(*&asd 05
S1E5
1x05
1x5


Output yang Diinginkan

234 Me 2 2013 1080p x264 5 1 BluRay S01 asd 05 S1E5 1x05 1x5
Umum
sumber
Bagaimana tepatnya upaya Anda tidak berhasil? Apa yang salah?
Runcing

Jawaban:

235

Sadarilah, itu \W meninggalkan garis bawah . Setara singkat untuk [^a-zA-Z0-9]akan[\W_]

text.replace(/[\W_]+/g," ");

\Wadalah negasi singkatan \w untuk [A-Za-z0-9_]karakter kata (termasuk garis bawah)

Contoh di regex101.com

Jonny 5
sumber
Periksa dan uji, belum punya banyak pengalaman di js-regex: p Senang Anda menyukainya
Jonny 5
6
Catatan yang \Wjuga akan mengenali karakter non-Latin sebagai karakter non-kata.
Tyblitz
1
Saya menandai jawaban ini dengan benar setelah bertahun-tahun, karena saya melihat ke belakang dan yang diterima tidak mengecualikan garis bawah
TheGeneral
143

Jonny 5 mengalahkan saya untuk itu. Saya akan menyarankan menggunakan \W+tanpa \sdi text.replace(/\W+/g, " "). Ini mencakup ruang putih juga.

T-CatSan
sumber
Terima kasih @ T-CatSan telah menunjukkan hal itu! Meningkatkannya, dan Saruman, Anda bebas untuk mengubah jawaban terbaik untuk apa pun :-) Tapi itu harus \W+, bukan [W+]Yah, selamat tahun baru semua!
Jonny 5
Terima kasih, @ Jonny5! Saya telah membuat perubahan yang Anda sarankan. Saya telah menguji dengan kurung sebelumnya dan sekarang saya melihatnya bekerja tanpa mereka. Selamat Tahun Baru juga.
T-CatSan
1
hey @ T-CatSan apakah ada cara untuk menambahkan pengecualian? Saya ingin menyimpan karakter &dan -. Ada tips?
Renato Gama
1
Saya membuat perubahan berikut / (\ W +) | (_) / g untuk mengabaikan _ juga. Tapi hanya bertanya-tanya mengapa tidak mengabaikan model pertama dan apakah regex saya adalah yang efisien.
Sridhar Gudimela
14

Karena [^a-z0-9]kelas karakter berisi semua yang bukan alnum, kelas itu juga mengandung karakter putih!

 text.replace(/[^a-z0-9]+/gi, " ");
Casimir et Hippolyte
sumber
6

Yah saya pikir Anda hanya perlu menambahkan quantifier untuk setiap pola. Juga hal carriage-return agak lucu:

text.replace(/[^a-z0-9]+|\s+/gmi, " ");

mengedit The \sHal pertandingan \rdan \njuga.

Runcing
sumber
Ya ada beberapa kebodohan di sana yang diperoleh dari jawaban lain pada topik, namun itu sangat membantu!
TheGeneral
2

A melihat pos berbeda yang juga memiliki tanda diakritik, yang sangat bagus

s.replace(/[^a-zA-Z0-9À-ž\s]/g, "")

Dmitri R117
sumber
2

Ini adalah posting lama saya, jawaban yang diterima sebagian besar baik. Namun saya memutuskan untuk membandingkan setiap solusi dan solusi yang jelas lainnya (hanya untuk bersenang-senang). Saya bertanya-tanya apakah ada perbedaan antara pola regex pada browser yang berbeda dengan string berukuran berbeda.

Jadi pada dasarnya saya menggunakan jsPerf pada

  • Pengujian di Chrome 65.0.3325 / Windows 10 0.0.0
  • Pengujian di Edge 16.16299.0 / Windows 10 0.0.0

Pola regex yang saya uji adalah

  • /[\W_]+/g
  • /[^a-z0-9]+/gi
  • /[^a-zA-Z0-9]+/g

Saya memuatnya dengan string panjang karakter acak

  • panjangnya 5000
  • panjang 1000
  • panjangnya 200

Contoh javascript yang saya gunakan var newstr = str.replace(/[\W_]+/g," ");

Setiap proses terdiri dari 50 atau lebih sampel pada setiap regex, dan saya menjalankannya 5 kali pada setiap browser.

Mari kita membalap kuda kita!

Hasil

                                Chrome                  Edge
Chars   Pattern                 Ops/Sec     Deviation   Op/Sec      Deviation
------------------------------------------------------------------------
5,000   /[\W_]+/g                19,977.80  1.09         10,820.40  1.32
5,000   /[^a-z0-9]+/gi           19,901.60  1.49         10,902.00  1.20
5,000   /[^a-zA-Z0-9]+/g         19,559.40  1.96         10,916.80  1.13
------------------------------------------------------------------------
1,000   /[\W_]+/g                96,239.00  1.65         52,358.80  1.41
1,000   /[^a-z0-9]+/gi           97,584.40  1.18         52,105.00  1.60
1,000   /[^a-zA-Z0-9]+/g         96,965.80  1.10         51,864.60  1.76
------------------------------------------------------------------------
  200   /[\W_]+/g               480,318.60  1.70        261,030.40  1.80
  200   /[^a-z0-9]+/gi          476,177.80  2.01        261,751.60  1.96
  200   /[^a-zA-Z0-9]+/g        486,423.00  0.80        258,774.20  2.15

Sejujurnya, Regex di kedua browser (dengan mempertimbangkan penyimpangan) hampir tidak bisa dibedakan, namun saya pikir jika dijalankan lebih sering lagi hasilnya akan menjadi sedikit lebih jelas (tetapi tidak banyak).

Skala teoretis untuk 1 karakter

                            Chrome                        Edge
Chars   Pattern             Ops/Sec     Scaled            Op/Sec    Scaled
------------------------------------------------------------------------
5,000   /[\W_]+/g            19,977.80  99,889,000       10,820.40  54,102,000
5,000   /[^a-z0-9]+/gi       19,901.60  99,508,000       10,902.00  54,510,000
5,000   /[^a-zA-Z0-9]+/g     19,559.40  97,797,000       10,916.80  54,584,000
------------------------------------------------------------------------

1,000   /[\W_]+/g            96,239.00  96,239,000       52,358.80  52,358,800
1,000   /[^a-z0-9]+/gi       97,584.40  97,584,400       52,105.00  52,105,000
1,000   /[^a-zA-Z0-9]+/g     96,965.80  96,965,800       51,864.60  51,864,600
------------------------------------------------------------------------

  200   /[\W_]+/g           480,318.60  96,063,720      261,030.40  52,206,080
  200   /[^a-z0-9]+/gi      476,177.80  95,235,560      261,751.60  52,350,320
  200   /[^a-zA-Z0-9]+/g    486,423.00  97,284,600      258,774.20  51,754,840

Saya tidak akan mengambil banyak ke dalam hasil ini karena ini tidak benar-benar perbedaan yang signifikan, yang bisa kita katakan adalah edge lebih lambat: o. Selain itu saya sangat bosan.

Pokoknya Anda bisa menjalankan benchmark sendiri.

Jsperf Tolok Ukur di sini

Umum
sumber
0

Untuk mengganti dengan tanda hubung, lakukan hal berikut:

text.replace(/[\W_-]/g,' ');
Gregory R.
sumber