JavaScript RegEx: Format string dengan panjang dinamis untuk memblokir format
Format RegEx berikut memberikan string ke pola blok keluaran berikut:
123456 78 90 (= 3 digit 3 digit 2 digit 2 digit)
RegEx:
string.replace(/^(\d{3})(\d{3})(\d{2})(\d{2})$/g, '$1 $2 $3 $4');
Contoh ini hanya berfungsi, jika string input yang diberikan cocok dengan panjang tepat 10 digit.
Bagaimana cara menyesuaikan RegEx agar berfungsi dengan setiap panjang string?
- 1234 -> 123 4
- 1234567 -> 123456 7
- 123456789 -> 123456 78 9
- 1234567890123 -> 123456 78 90 12 3
Latar Belakang: Saya ingin memformat string input dari bidang input formulir secara langsung, ketika pengguna memasukkan nomor ...
Jawaban
Menggunakan tampilan Javascript modern yang memungkinkan pernyataan panjang dinamis, Anda dapat menggunakan ekspresi reguler ini untuk mencocokkan:
/(?<=^(?:\d{6}(?:\d{2})*|(?:\d{3}){1,2}))(?=\d+$)/g
Ganti saja dengan satu spasi yaitu " "
Demo RegEx
Lihat kebelakang:
(?<=: Mulai pernyataan^(?:\d{6}(?:\d{2})*: Pastikan kita memiliki 6 digit diikuti dengan 0 atau lebih pasangan digit di belakang|: ATAU(?:\d{3}){1,2}): Buatlah kita memiliki satu atau dua set set 3 digit di belakang
): Akhiri pernyataan
Lihat ke depan:
(?=\d+$): Pastikan kami memiliki setidaknya satu digit di depan
Solusi anubhava dan Wiktor pintar, tapi saya rasa saya tidak akan menggunakan ekspresi reguler untuk melakukannya; solusi terasa terlalu rumit untuk dipertahankan. (Ini adalah panggilan penilaian.) Berikut adalah pendekatan yang mendapatkan digit individu dan menyisipkan spasi setelah digit ketiga dan setelah setiap digit berikutnya yang posisi indeksnya adalah angka ganjil:
result = [...str].map((d, i) => d + (i === 2 || (i >= 5 && i % 2 === 1) ? " " : "")).join("");
Contoh Langsung:
const tests = [
["1234", "123 4"],
["1234567", "123 456 7"],
["123456789", "123 456 78 9"],
["1234567890123", "123 456 78 90 12 3"],
];
function format(str) {
return [...str].map((d, i) => d + (i === 2 || (i >= 5 && i % 2 === 1) ? " " : "")).join("");
}
for (const [str, expected] of tests) {
const result = format(str);
console.log(`|${str}|`, "=>", `|${result}|`, result === expected ? "OK" : "*** ERROR");
}
Berikut adalah versi yang berfungsi di lingkungan khusus ES5:
result = str.split("").map(function(d, i) {
return d + (i === 2 || (i >= 5 && i % 2 === 1) ? " " : "");
}).join("");
Kamu bisa memakai
const rx = /^(\d{3})(\d{1,3})?(\d{1,2})?(\d{1,2})?$/; $('body').on('input', '.info', function(e) {
this.value = this.value.replace(/\s+/g,'')
.replace(/^(\d{10}).*/, '$1') .replace(rx, (_,w,x,y,z) => z ? `${w} ${x} ${y} ${z}` : y ? `${w} ${x} ${y}` :
x ? `${w} ${x}` : w);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input class="info" maxlength=13>
The ^(\d{3})(\d{1,3})?(\d{1,2})?(\d{1,2})?$regex akan melakukan format hidup bersama-sama dengan fungsi callback digunakan sebagai argumen pengganti. Tiga digit pertama wajib diisi, blok kedua, ketiga dan keempat bersifat opsional, tetapi mengandung setidaknya satu digit. Spasi hanya ditambahkan jika setidaknya ada satu digit di blok. Nomor diformat ulang setiap kali nomor diedit:
.replace(/\s+/g,'')menghapus spasi yang ditambahkan.replace(/^(\d{10}).*/, '$1')hanya menyimpan sepuluh digit pertama jika ada lebih banyak