javascript - Bolehkah kita menggunakan regex untuk menyelesaikan berbilang peraturan sekaligus?


Saya perlu menghalang beberapa interaksi input pengguna dan yang terlintas di fikiran saya ialah regex serta-merta.

Saya akan menulis terlebih dahulu sebaik mungkin apa yang perlu saya capai dan kemudian saya akan menyiarkan kod yang saya tulis untuk mencapai kebanyakan daripada ini, tetapi masih belum sempurna...

  • Ambil tali itu
  • Jangan benarkan ia mula menaip dengan ruang
  • Jangan benarkan beberapa ruang berturut-turut
  • Jangan benarkan beberapa titik berturut-turut
  • Jangan benarkan apostrof berganda
  • Benarkan aksara berikut [a-z] '.
  • Jangan benarkan rentetan melebihi 14 aksara

Sekarang, ini adalah kod saya:

this.name = this.name
  .replace(/^[\s]+/, '')     // prevent starting with space
  .replace(/\s\s+/, ' ')     // prevent multiplace spaces
  .replace(/\.\./, '.')      // prevent multiple dots
  .replace(/''/, '\'')       // prevent multiple apostrophies
  .replace(/[^ a-z'.]/i, '') // allowed
  .toUpperCase()             // transform
  .substring(0, 14)          // do not allow more than 14 characters

Soalan :

  • Bolehkah kita dan bagaimana jika ya, melaksanakan semua atau kebanyakan peraturan regex ini dalam satu gantian?

  • Bagaimana saya boleh membaiki/meningkatkan peraturan regex saya supaya tidak membenarkan lebih daripada satu ., saya telah menetapkannya supaya tidak membenarkan kemasukan berterusan, tetapi pengguna boleh menggunakan dua titik seperti M.G.K - walaupun saya ingin membenarkan hanya satu kemasukan . dalam keseluruhan string?

  • Sama seperti di atas, tetapi untuk ' (tanda petik tunggal)?

Jawapan #1

Keperluan pertama untuk "menjejalkan" segala-galanya ke dalam 1 operasi penggantian regex agak mudah dilaksanakan, kerana semua penggantian yang perlu anda lakukan ialah menggunakan char yang anda padankan. Anda boleh menggunakan .replace(/^\s+|( \s)\s+|(\.)\.|(')'|[^a-z'.]+/ig, '$1$2$3'), lihat demo regex ini.

Butiran

  • ^\s+ - permulaan rentetan (^) dan kemudian 1+ ruang kosong
  • | - atau
  • (\s)\s+ - satu ruang kosong ditangkap ke dalam Kumpulan 1 dan kemudian 1+ aksara ruang kosong
  • | - atau
  • (\.)\. - satu . ditangkap ke dalam Kumpulan 2, dan kemudian satu .
  • | - atau
  • (')' - satu ' ditangkap ke dalam Kumpulan 3 dan kemudian satu '
  • | - atau
  • [^a-z'.]+ - 1 atau lebih aksara selain daripada ruang, huruf ASCII, ' dan ..

Pemodifikasi /i menjadikan a-z sepadan dalam cara yang tidak sensitif huruf besar/kecil, g membolehkan padanan berganda. $1 merujuk kepada nilai dalam Kumpulan 1, $2 merujuk kepada nilai dalam Kumpulan 2 dan $3 merujuk kepada nilai Kumpulan 3. Perlu diperhatikan bahawa jika mereka tidak dipadankan, nilai-nilai dalam kumpulan ini adalah rentetan kosong, oleh itu kita boleh menggunakan ketiga-tiganya bersama dalam satu corak penggantian rentetan.

Keperluan kedua dan ketiga memerlukan dua operasi gantian regex yang berasingan lagi. Maksudnya adalah untuk memadankan dan menangkap semua aksara sehingga kejadian kedua ' dan . dan hanya memadankan kejadian kedua ' dan ., kemudian menggantikannya dengan rujukan balik kepada kumpulan pertama: 1) .replace(/^([^']*'[^']*)'/, '$1') (demo) dan 2) .replace(/^([^.]*\.[^.]*)\./, '$1') (demo).

Butiran

  • ^ - sauh permulaan rentetan
  • ([^']*'[^']*) - Kumpulan 1:

    • [^']* - mana-mana 0+ aksara selain ' (sebuah [^...] adalah kelas aksara yang dinafikan yang memadankan mana-mana aksara selain yang ditakrifkan di dalam kelas)
    • ' - satu tanda petikan tunggal
    • [^']* - sebarang 0+ aksara selain '
  • ' - tanda petik tunggal.

Padanan ini digantikan dengan $1, kandungan kumpulan tangkapan pertama.

Corak ketiga adalah serupa dengan corak kedua, cuma ' digantikan dengan ./\. (perhatikan bahawa di dalam kelas aksara, . dianggap sebagai . literal, ia tidak sepadan dengan sebarang aksara kecuali aksara pemisah baris di dalam [...]).