Ekspresi Reguler untuk Mencocokkan Simbol:! $% ^ & * () _ + | ~ - = `{} []:"; '<>?,. /

96

Saya mencoba membuat tes Regex di JavaScript yang akan menguji string berisi salah satu dari karakter ini:

!$%^&*()_+|~-=`{}[]:";'<>?,./

Info Lebih Lanjut Jika Anda Tertarik :)

Ini untuk aplikasi perubahan kata sandi yang cukup keren yang sedang saya kerjakan. Jika Anda tertarik, inilah kode lainnya.

Saya memiliki tabel yang mencantumkan persyaratan kata sandi dan saat pengguna akhir mengetik kata sandi baru, itu akan menguji array Regexes dan memberi tanda centang di baris tabel yang sesuai jika ... memeriksa :) Saya hanya perlu menambahkan yang ini sebagai ganti item ke-4 dalam validationarray.

var validate = function(password){
    valid = true;

    var validation = [
        RegExp(/[a-z]/).test(password), RegExp(/[A-Z]/).test(password), RegExp(/\d/).test(password), 
        RegExp(/\W|_/).test(password), !RegExp(/\s/).test(password), !RegExp("12345678").test(password), 
        !RegExp($('#txtUsername').val()).test(password), !RegExp("cisco").test(password), 
        !RegExp(/([a-z]|[0-9])\1\1\1/).test(password), (password.length > 7)
    ]

    $.each(validation, function(i){
        if(this)
            $('.form table tr').eq(i+1).attr('class', 'check');
        else{
            $('.form table tr').eq(i+1).attr('class', '');
            valid = false
        }
    });

    return(valid);

}

Ya, ada juga validasi sisi server yang sesuai!

pixelbobby
sumber
9
Sangat lucu bahwa jawaban atas pertanyaan Anda terletak pada judul dengan pengecualian karakter khusus yang keluar dan garis miring ke depan.
sciritai
1
Mengapa tidak menggunakan .addClass("check")dan .removeClass("check")? Dan melihat if (someBoolean == true)kode selalu membuatku ngeri. Lakukan saja if (someBoolean). Atau, lebih baik lagi, lakukan saja $(".form table tr").eq(i+1).toggleClass("check", !!this); valid = valid && !!this;.
gilly3
+1 @ gill3 thx untuk ulasan kode- umpan balik yang bagus. Saya telah menggunakan metode tangan pendek di masa lalu.
pixelbobby
@ gilly3, tampaknya berfungsi dengan baik di FF tetapi! IE8. suka tangan pendek ini. Saya mencoba untuk mencari tahu apa yang dilakukan IE8 secara berbeda.
pixelbobby

Jawaban:

174

Ekspresi reguler untuk ini sangat sederhana. Cukup gunakan kelas karakter. Tanda hubung adalah karakter khusus dalam kelas karakter, jadi harus menjadi yang pertama:

/[-!$%^&*()_+|~=`{}\[\]:";'<>?,.\/]/

Anda juga harus melepaskan karakter meta ekspresi reguler lainnya.

Sunting: Tanda hubung itu khusus karena dapat digunakan untuk mewakili berbagai karakter. Kelas karakter yang sama ini dapat disederhanakan dengan rentang seperti ini:

/[$-/:-?{-~!"^_`\[\]]/

Ada tiga rentang. '$' to '/', ':' to '?', dan '{' to '~'. string karakter terakhir tidak dapat direpresentasikan secara lebih sederhana dengan range:! "^ _` [].

Gunakan tabel ACSII untuk menemukan rentang kelas karakter.

Jeff Hillman
sumber
Mengapa tidak disebutkan bilangan \ Q dan \ E untuk keluar dari urutan karakter?
SerG
Sebelum menemukan solusi ini, saya akan menyusuri rute pengecualian kelas karakter: cocokkan semuanya TAPI alfa, angka, spasi, dll.
Pete Alvin
1
Apakah sudah menjadi rahasia umum bahwa tanda hubung harus didahulukan? Saya sudah membaca lusinan SO jawaban dan lembar contekan regex ini yang pertama kali saya dengar. Jawaban Anda menyelamatkan saya dari banyak drama. Terima kasih!
CF_HoneyBadger
2
@SerG \Qdan \Ejangan bekerja di mesin JS RegExp :(/^\Q.\E$/.test('Q+E'); // true
Paul S.
1
@ q4w56 garis miring terbalik tidak ada dalam rangkaian karakter yang ditentukan dalam pertanyaan asli, jadi tidak cocok dengan garis miring terbalik adalah benar. :)
Jeff Hillman
7

Cara paling sederhana dan terpendek untuk melakukannya:

/[^\p{L}\d\s@#]/u

Penjelasan

[^...] Cocok dengan satu karakter yang tidak ada dalam daftar di bawah

  • \p{L} => cocok dengan semua jenis huruf dari bahasa apapun

  • \d => cocok dengan angka nol sampai sembilan

  • \s => cocok dengan semua jenis karakter yang tidak terlihat

  • @# => @dan #karakter

Jangan lupa untuk meneruskan uflag (unicode).

AmirZpr
sumber
bukankah Anda memerlukan ^ untuk menunjukkan tidak?
Webber
1
@Webber Tidak. Mereka dalam modal dan ini membuat pernyataan negatif. ^dibutuhkan saat kita menggunakan \wdan \sdalam huruf kecil.
AmirZpr
3
Bukankah ini menafsirkannya sehingga baik di luar watau di luar s, dan karena keduanya tidak benar-benar berpotongan, itu hanya memungkinkan melalui semua karakter? (Jadi tidak menyaring apa pun.)
Zael
2
@Zael Anda benar, ekspresi reguler seperti yang dinyatakan ( /[\W\S]/) membiarkan semuanya masuk. Representasi yang lebih akurat tentang apa yang saya yakini akan dicapai oleh Amir [^\w\s]. Pada yang pertama, ekspresi reguler mengatakan "cocokkan apa pun yang bukan alfanumerik ATAU yang bukan spasi putih", yang seperti yang Anda sebutkan, mari semuanya berjalan karena karakter alfanumerik bukan spasi putih dan sebaliknya. Yang terakhir mengatakan "cocokkan apa pun yang bukan alfanumerik DAN yang bukan spasi". Tentu saja, pengecualian berlaku jika karakter beraksen (suka À) dicocokkan dengan [^\w\s].
Jesse
ini tidak termasuk _ char
MikeSchem
5

Menjawab

/[\W\S_]/

Penjelasan

Ini membuat kelas karakter menghapus karakter kata, karakter spasi, dan menambahkan kembali karakter garis bawah (karena garis bawah adalah karakter "kata"). Yang tersisa hanyalah karakter khusus. Huruf kapital mewakili negasi dari huruf kecil.

\Wakan memilih semua karakter non "kata" yang setara dengan [^a-zA-Z0-9_]
\Sakan memilih semua karakter non "spasi putih" yang setara dengan [ \t\n\r\f\v]
_akan memilih "_" karena kita meniadakannya saat menggunakan \Wdan perlu menambahkannya kembali

MikeSchem
sumber
MikeSchem, Anda baru saja membawa saya melalui mesin waktu.
pixelbobby
ya, saya menyadarinya. sudah tua, tetapi saya merasa jawaban yang paling sederhana belum diposting.
MikeSchem
bagaimana ini berbeda dari jawaban di bawah yang gagal pada garis bawah?
sf8193
-1
// The string must contain at least one special character, escaping reserved RegEx characters to avoid conflict
  const hasSpecial = password => {
    const specialReg = new RegExp(
      '^(?=.*[!@#$%^&*"\\[\\]\\{\\}<>/\\(\\)=\\\\\\-_´+`~\\:;,\\.€\\|])',
    );
    return specialReg.test(password);
  };
Arni Gudjonsson
sumber
Jangan gunakan RegExpkonstruktor saat Anda bisa menggunakan literal regex. Jauh lebih sedikit pekerjaan melarikan diri (yang sebagian besar tidak perlu), dan itu lebih efisien juga.
Bergi
Mengapa menggunakan lookahead yang rumit ketika Anda bisa langsung mencocokkan karakternya?
Bergi
Bisakah Anda memberi contoh @Bergi? Saya tidak mengerti apa yang Anda sarankan.
Arni Gudjonsson
-1

Cara sederhana untuk mencapai ini adalah himpunan negatif [^ \ w \ s]. Ini pada dasarnya menangkap:

  • Apa pun yang bukan karakter alfanumerik (huruf dan angka)
  • Apa pun yang bukan spasi, tab, atau baris baru (secara kolektif disebut sebagai spasi)

Untuk beberapa alasan [\ W \ S] tidak bekerja dengan cara yang sama, ia tidak melakukan pemfilteran apa pun. Komentar Zael di salah satu jawaban memberikan penjelasan.

Harfel Jaquez
sumber
Tidak, garis bawah hilang dan semua karakter di luar rentang ascii dan sebagian besar karakter kontrol dalam rentang ascii akan cocok dengan kelas ini. /[^\w\s]/.test('é') # true, /[^\w\s]/.test('_') # false.
Casimir et Hippolyte
-7

Ganti semua latters dari bahasa apa pun di 'A', dan jika Anda ingin, misalnya, semua angka menjadi 0:

return str.replace(/[^\s!-@[-`{-~]/g, "A").replace(/\d/g, "0");
Yaron Landau
sumber
23
Pertanyaan apa yang Anda jawab?
Toto