Saya telah melihat Stack Overflow ( mengganti karakter .. eh , bagaimana JavaScript tidak mengikuti standar Unicode tentang RegExp , dll.) Dan belum benar-benar menemukan jawaban konkret untuk pertanyaan:
How can JavaScript match for accented characters (those with diacritical marks)?
Saya memaksa sebuah bidang di UI agar sesuai dengan format: last_name, first_name
(terakhir [koma spasi] pertama) , dan saya ingin memberikan dukungan untuk diakritik, tetapi jelas dalam JavaScript itu sedikit lebih sulit daripada bahasa / platform lain.
Ini adalah versi asli saya, sampai saya ingin menambahkan dukungan diakritik:
/^[a-zA-Z]+,\s[a-zA-Z]+$/
Saat ini saya sedang memperdebatkan satu dari tiga metode untuk menambah dukungan, yang semuanya telah saya uji dan bekerja (setidaknya sampai batas tertentu, saya tidak benar-benar tahu apa "tingkat" dari pendekatan kedua). Di sini mereka:
Secara eksplisit mendaftar semua karakter beraksen yang ingin saya terima valid (lumpuh dan terlalu rumit):
var accentedCharacters = "àèìòùÀÈÌÒÙáéíóúýÁÉÍÓÚÝâêîôûÂÊÎÔÛãñõÃÑÕäëïöüÿÄËÏÖÜŸçÇßØøÅåÆæœ";
// Build the full regex
var regex = "^[a-zA-Z" + accentedCharacters + "]+,\\s[a-zA-Z" + accentedCharacters + "]+$";
// Create a RegExp from the string version
regexCompiled = new RegExp(regex);
// regexCompiled = /^[a-zA-ZàèìòùÀÈÌÒÙáéíóúýÁÉÍÓÚÝâêîôûÂÊÎÔÛãñõÃÑÕäëïöüÿÄËÏÖÜŸçÇßØøÅåÆæœ]+,\s[a-zA-ZàèìòùÀÈÌÒÙáéíóúýÁÉÍÓÚÝâêîôûÂÊÎÔÛãñõÃÑÕäëïöüÿÄËÏÖÜŸçÇßØøÅåÆæœ]+$/
- Ini dengan benar mencocokkan nama belakang / depan dengan salah satu karakter beraksen yang didukung di
accentedCharacters
.
Pendekatan saya yang lain adalah menggunakan .
kelas karakter, untuk memiliki ekspresi yang lebih sederhana:
var regex = /^.+,\s.+$/;
- Ini akan cocok untuk apa saja, setidaknya dalam bentuk:
something, something
. Saya kira tidak apa-apa ...
Pendekatan terakhir, yang baru saja saya temukan mungkin lebih sederhana ...
/^[a-zA-Z\u00C0-\u017F]+,\s[a-zA-Z\u00C0-\u017F]+$/
- Ini cocok dengan berbagai karakter unicode - diuji dan bekerja, meskipun saya tidak mencoba sesuatu yang gila, hanya hal-hal normal yang saya lihat di departemen bahasa kami untuk nama anggota fakultas.
Inilah kekhawatiran saya:
- Solusi pertama terlalu terbatas, dan ceroboh dan berbelit-belit pada saat itu. Itu perlu diubah jika saya lupa satu atau dua karakter, dan itu tidak terlalu praktis.
- Solusi kedua lebih baik, ringkas, tetapi mungkin lebih cocok daripada yang seharusnya. Saya tidak bisa menemukan dokumentasi nyata pada persis apa yang
.
cocok, hanya generalisasi "karakter apapun kecuali karakter baris baru" (dari meja di MDN ). Solusi ketiga tampaknya menjadi yang paling tepat, tetapi apakah ada gotcha? Saya tidak terlalu akrab dengan Unicode, setidaknya dalam prakteknya, tetapi melihat tabel kode / kelanjutan dari tabel itu ,
\u00C0-\u017F
tampaknya cukup solid, setidaknya untuk input yang saya harapkan.- Fakultas tidak akan mengirimkan formulir dengan nama mereka dalam bahasa asli mereka (misalnya, Arab, Cina, Jepang, dll.) Jadi saya tidak perlu khawatir tentang karakter yang tidak sesuai dengan karakter Latin
Jadi pertanyaan sebenarnya : Manakah dari tiga pendekatan ini yang paling cocok untuk tugas itu? Atau adakah solusi yang lebih baik?
sumber
regex = /^[^,]+,\s[^,]+$/;
untuk mencegahnya..
atom cocok apa-apa kecuali baris " sebenarnya cukup tepat :-)Jawaban:
Cara lebih mudah untuk menerima semua aksen adalah ini:
Lihat https://unicode-table.com/en/ untuk karakter yang tercantum dalam urutan angka.
sumber
-
mendefinisikan rentang, dan teknik ini mengeksploitasi urutan karakter di charset untuk menentukan rentang kontinu, membuat solusi super ringkas untuk masalahZ
dana
)?Rentang aksen Latin
\u00C0-\u017F
tidak cukup untuk basis data nama saya, jadi saya memperpanjang regex keSaya menambahkan blok kode ini (
\u00C0-\u024F
termasuk tiga blok yang berdekatan sekaligus):\u00C0-\u00FF
Suplemen Latin-1\u0100-\u017F
Latin Extended-A\u0180-\u024F
Latin Extended-B\u1E00-\u1EFF
Latin Diperpanjang TambahanPerhatikan bahwa
\u00C0-\u00FF
sebenarnya hanya bagian dari Suplemen Latin-1 . Rentang itu melompati sinyal kontrol yang tidak patut dan semua simbol kecuali untuk multiply × yang ditempatkan dengan canggung\u00D7
dan bagi ÷\u00F7
.Jika Anda membutuhkan lebih banyak poin kode, Anda dapat menemukan rentang lebih banyak di Daftar karakter Unicode Wikipedia . Misalnya, Anda juga bisa menambahkan Latin Extended-C , D , dan E , tetapi saya meninggalkannya karena hanya sejarawan yang tampaknya tertarik pada mereka sekarang, dan set D dan E bahkan tidak merender dengan benar di browser saya.
Regex asli berhenti pada
\u017F
tersumbat pada nama "Șenol". Menurut FontSpace's Unicode Analyzer , karakter pertama adalah\u0218
, LATIN MODAL SURAT S DENGAN COMMA DI BAWAH. (Ya, itu biasanya dieja dengan cedilla-S\u015E
, "Şenol." Tapi aku tidak terbang ke Turki untuk pergi memberitahunya, "Kau salah mengeja namamu!")sumber
[a-zA-Z\u00c0-\u024f\u1e00-\u1eff]
Tergantung pada tugas :-) Untuk mencocokkan dengan tepat semua karakter Latin dan versi beraksennya, rentang Unicode mungkin memberikan solusi terbaik. Mereka mungkin diperluas ke semua karakter non-spasi, yang bisa dilakukan menggunakan
\S
kelas karakter.Masalah paling mendasar yang saya lihat di sini bukanlah diakritik, tetapi spasi putih. Ada beberapa nama yang terdiri dari beberapa kata, misalnya untuk judul. Jadi, Anda harus menggunakan yang paling umum, yang memungkinkan segalanya kecuali koma yang membedakan pertama dari nama belakang:
Tetapi solusi kedua Anda dengan
.
kelas karakter sama baiknya, Anda hanya perlu peduli dengan beberapa komata.sumber
any_character_not_a_comma, any_character_not_a_comma
? Itulah yang saya pikirkan ketika pertama kali membacanya, saya agak bingung ketika melihat tiga koma di sana.s
untuk ruang putih ...[^\s]
ke\S
The XRegExp perpustakaan memiliki plugin bernama Unicode yang membantu menyelesaikan tugas-tugas seperti ini.
Itu disebutkan dalam komentar untuk pertanyaan, tetapi mudah untuk dilewatkan. Saya perhatikan hanya setelah saya mengirimkan jawaban ini.
sumber
anything, anything
. Ini akan bermanfaat bagi pembaca masa depan :)Bagaimana dengan ini?
sumber
Šš
.Bagaimana dengan ini?
Ini akan cocok dengan setiap kata dengan karakter beraksen atau tidak.
sumber
dari wiki ini: https://en.wikipedia.org/wiki/List_of_Unicode_characters#Basic_Latin
untuk huruf latin, saya gunakan
itu menghindari tanda hubung dan spesial karakter
sumber
Penjelasan:
\pL
- Cocok dengan segala jenis huruf dari bahasa apa pun\pM
- Atches karakter yang dimaksudkan untuk dikombinasikan dengan karakter lain (misalnya aksen, umlaut, kotak terlampir, dll)\p{Zs}
- Cocok dengan karakter spasi putih yang tidak terlihat, tetapi tidak memakan ruangu
- Pola dan string subjek diperlakukan sebagai UTF-8Tidak seperti regex yang diusulkan lainnya (seperti
[A-Za-zÀ-ÖØ-öø-ÿ]
), ini akan bekerja dengan semua karakter khusus bahasa, misalnyaŠš
dicocokkan dengan aturan ini, tetapi tidak dicocokkan oleh orang lain di halaman ini.Sayangnya, aslinya JavaScript tidak mendukung kelas-kelas ini. Namun, Anda dapat menggunakan
xregexp
, missumber
Anda dapat menghapus diakritik dari huruf dengan menggunakan:
Ini akan menghapus semua tanda diakritik, dan kemudian melakukan regex Anda di atasnya
Referensi:
https://thread.engineering/2018-08-29-searching-and-sorting-text-with-diacritical-marks-in-javascript/
sumber