Saya memiliki ekspresi reguler yang sangat panjang, yang ingin saya bagi menjadi beberapa baris dalam kode JavaScript saya agar setiap baris memiliki panjang 80 karakter sesuai dengan aturan JSLint. Itu lebih baik untuk membaca, saya pikir. Berikut contoh polanya:
var pattern = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
javascript
regex
jslint
expression
readability
Nik Sumeiko
sumber
sumber
/\S+@\S+\.\S+/
?Jawaban:
Anda dapat mengubahnya menjadi string dan membuat ekspresi dengan memanggil
new RegExp()
:var myRE = new RegExp (['^(([^<>()[\]\\.,;:\\s@\"]+(\\.[^<>(),[\]\\.,;:\\s@\"]+)*)', '|(\\".+\\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.', '[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\\.)+', '[a-zA-Z]{2,}))$'].join(''));
Catatan:
RegExp
menerima pengubah sebagai parameter kedua/regex/g
=>new RegExp('regex', 'g')
[ Tambahan ES20xx (template dengan tag)]
Di ES20xx Anda dapat menggunakan template yang diberi tag . Lihat cuplikannya.
catatan:
\s
,\s+
,\s{1,x}
,\t
,\n
dll).(() => { const createRegExp = (str, opts) => new RegExp(str.raw[0].replace(/\s/gm, ""), opts || ""); const yourRE = createRegExp` ^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)| (\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])| (([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$`; console.log(yourRE); const anotherLongRE = createRegExp` (\byyyy\b)|(\bm\b)|(\bd\b)|(\bh\b)|(\bmi\b)|(\bs\b)|(\bms\b)| (\bwd\b)|(\bmm\b)|(\bdd\b)|(\bhh\b)|(\bMI\b)|(\bS\b)|(\bMS\b)| (\bM\b)|(\bMM\b)|(\bdow\b)|(\bDOW\b) ${"gi"}`; console.log(anotherLongRE); })();
sumber
new RegExp
adalah cara yang bagus untuk ekspresi reguler multiline. Alih-alih menggabungkan array, Anda bisa menggunakan operator penggabungan string:var reg = new RegExp('^([a-' + 'z]+)$','i');
//
) dan menempelkannya sebagai argumen string ke konstruktor RegExp. Ini karena karakter garis miring terbalik dikonsumsi saat mengevaluasi string literal . Contoh:/Hey\sthere/
tidak bisa diganti dengannew RegExp("Hey\sthere")
. Sebaliknya itu harus diganti dengannew RegExp("Hey\\sthere")
catatan garis miring terbalik ekstra! Oleh karena itu saya lebih suka meninggalkan literal regex panjang pada satu baris panjangRegExp
cara yang lebih mudah dipahami.Memperluas jawaban @KooiInc, Anda bisa menghindari pelolosan setiap karakter khusus secara manual dengan menggunakan
source
propertiRegExp
objek.Contoh:
var urlRegex= new RegExp('' + /(?:(?:(https?|ftp):)?\/\/)/.source // protocol + /(?:([^:\n\r]+):([^@\n\r]+)@)?/.source // user:pass + /(?:(?:www\.)?([^\/\n\r]+))/.source // domain + /(\/[^?\n\r]+)?/.source // request + /(\?[^#\n\r]*)?/.source // query + /(#?[^\n\r]*)?/.source // anchor );
atau jika Anda ingin menghindari pengulangan
.source
properti, Anda dapat melakukannya menggunakanArray.map()
fungsi:var urlRegex= new RegExp([ /(?:(?:(https?|ftp):)?\/\/)/ // protocol ,/(?:([^:\n\r]+):([^@\n\r]+)@)?/ // user:pass ,/(?:(?:www\.)?([^\/\n\r]+))/ // domain ,/(\/[^?\n\r]+)?/ // request ,/(\?[^#\n\r]*)?/ // query ,/(#?[^\n\r]*)?/ // anchor ].map(function(r) {return r.source}).join(''));
Di ES6, fungsi peta dapat dikurangi menjadi:
.map(r => r.source)
sumber
combineRegex = (...regex) => new RegExp(regex.map(r => r.source).join(""))
Penggunaan:combineRegex(/regex1/, /regex2/, ...)
Menggunakan string dalam
new RegExp
canggung karena Anda harus menghindari semua garis miring terbalik. Anda dapat menulis regex yang lebih kecil dan menggabungkannya.Mari kita pisahkan regex ini
Kami akan menggunakan fungsi untuk membuat segalanya lebih indah nanti
function multilineRegExp(regs, options) { return new RegExp(regs.map( function(reg){ return reg.source; } ).join(''), options); }
Dan sekarang mari bergoyang
var r = multilineRegExp([ /^foo/, // we can add comments too /(.*)/, /\bar$/ ]);
Karena ada biaya, coba buat regex asli hanya sekali, lalu gunakan.
sumber
multilineRegExp([/a|b/, /c|d])
menghasilkan/a|bc|d/
, sementara yang Anda maksud(a|b)(c|d)
.Berkat dunia literal template yang menakjubkan, Anda sekarang dapat menulis regex bersarang besar, multi-baris, memiliki komentar yang baik, dan bahkan semantik di ES6.
//build regexes without worrying about // - double-backslashing // - adding whitespace for readability // - adding in comments let clean = (piece) => (piece .replace(/((^|\n)(?:[^\/\\]|\/[^*\/]|\\.)*?)\s*\/\*(?:[^*]|\*[^\/])*(\*\/|)/g, '$1') .replace(/((^|\n)(?:[^\/\\]|\/[^\/]|\\.)*?)\s*\/\/[^\n]*/g, '$1') .replace(/\n\s*/g, '') ); window.regex = ({raw}, ...interpolations) => ( new RegExp(interpolations.reduce( (regex, insert, index) => (regex + insert + clean(raw[index + 1])), clean(raw[0]) )) );
Dengan menggunakan ini, Anda sekarang dapat menulis ekspresi reguler seperti ini:
let re = regex`I'm a special regex{3} //with a comment!`;
Keluaran
/I'm a special regex{3}/
Atau bagaimana dengan multiline?
'123hello' .match(regex` //so this is a regex //here I am matching some numbers (\d+) //Oh! See how I didn't need to double backslash that \d? ([a-z]{1,3}) /*note to self, this is group #2*/ `) [2]
Hasil
hel
, rapi!"Bagaimana jika saya benar-benar perlu mencari baris baru?", Baiklah gunakan
\n
konyol!Bekerja di Firefox dan Chrome saya.
Oke, "bagaimana dengan sesuatu yang sedikit lebih rumit?"
Tentu, ini adalah bagian dari objek yang merusak parser JS yang saya kerjakan :
regex`^\s* ( //closing the object (\})| //starting from open or comma you can... (?:[,{]\s*)(?: //have a rest operator (\.\.\.) | //have a property key ( //a non-negative integer \b\d+\b | //any unencapsulated string of the following \b[A-Za-z$_][\w$]*\b | //a quoted string //this is #5! ("|')(?: //that contains any non-escape, non-quote character (?!\5|\\). | //or any escape sequence (?:\\.) //finished by the quote )*\5 ) //after a property key, we can go inside \s*(:|) | \s*(?={) ) ) ((?: //after closing we expect either // - the parent's comma/close, // - or the end of the string \s*(?:[,}\]=]|$) | //after the rest operator we expect the close \s*\} | //after diving into a key we expect that object to open \s*[{[:] | //otherwise we saw only a key, we now expect a comma or close \s*[,}{] ).*) $`
Ini menghasilkan
/^\s*((\})|(?:[,{]\s*)(?:(\.\.\.)|(\b\d+\b|\b[A-Za-z$_][\w$]*\b|("|')(?:(?!\5|\\).|(?:\\.))*\5)\s*(:|)|\s*(?={)))((?:\s*(?:[,}\]=]|$)|\s*\}|\s*[{[:]|\s*[,}{]).*)$/
Dan menjalankannya dengan sedikit demo?
let input = '{why, hello, there, "you huge \\"", 17, {big,smelly}}'; for ( let parsed; parsed = input.match(r); input = parsed[parsed.length - 1] ) console.log(parsed[1]);
Keluaran berhasil
{why , hello , there , "you huge \"" , 17 , {big ,smelly } }
Perhatikan keberhasilan menangkap string yang dikutip.
Saya mengujinya di Chrome dan Firefox, berhasil!
Jika penasaran, Anda dapat melihat apa yang saya lakukan , dan peragaannya .
Meskipun hanya berfungsi di Chrome, karena Firefox tidak mendukung referensi latar atau grup bernama. Jadi perhatikan bahwa contoh yang diberikan dalam jawaban ini sebenarnya adalah versi yang disterilkan dan mungkin dengan mudah ditipu untuk menerima string yang tidak valid.
sumber
Ada jawaban yang bagus di sini, tetapi untuk kelengkapan seseorang harus menyebutkan fitur inti Javascript dari pewarisan dengan rantai prototipe . Sesuatu seperti ini menggambarkan idenya:
RegExp.prototype.append = function(re) { return new RegExp(this.source + re.source, this.flags); }; let regex = /[a-z]/g .append(/[A-Z]/) .append(/[0-9]/); console.log(regex); //=> /[a-z][A-Z][0-9]/g
sumber
Regex di atas kehilangan beberapa garis miring hitam yang tidak berfungsi dengan benar. Jadi, saya mengedit regex. Harap pertimbangkan regex ini yang berfungsi 99,99% untuk validasi email.
let EMAIL_REGEXP = new RegExp (['^(([^<>()[\\]\\\.,;:\\s@\"]+(\\.[^<>()\\[\\]\\\.,;:\\s@\"]+)*)', '|(".+"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.', '[0-9]{1,3}\])|(([a-zA-Z\\-0-9]+\\.)+', '[a-zA-Z]{2,}))$'].join(''));
sumber
Untuk menghindari Array
join
, Anda juga dapat menggunakan sintaks berikut:var pattern = new RegExp('^(([^<>()[\]\\.,;:\s@\"]+' + '(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@' + '((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|' + '(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$');
sumber
Secara pribadi, saya akan menggunakan regex yang tidak terlalu rumit:
Tentu, ini kurang akurat dari pola Anda saat ini, tetapi apa yang ingin Anda capai? Apakah Anda mencoba menemukan kesalahan yang tidak disengaja yang mungkin masuk pengguna, atau Anda khawatir pengguna Anda mungkin mencoba memasukkan alamat yang tidak valid? Jika itu yang pertama, saya akan memilih pola yang lebih mudah. Jika yang terakhir, beberapa verifikasi dengan menanggapi email yang dikirim ke alamat itu mungkin merupakan pilihan yang lebih baik.
Namun, jika Anda ingin menggunakan pola Anda saat ini, akan (IMO) lebih mudah dibaca (dan dipelihara!) Dengan membangunnya dari sub-pola yang lebih kecil, seperti ini:
var box1 = "([^<>()[\]\\\\.,;:\s@\"]+(\\.[^<>()[\\]\\\\.,;:\s@\"]+)*)"; var box2 = "(\".+\")"; var host1 = "(\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\])"; var host2 = "(([a-zA-Z\-0-9]+\\.)+[a-zA-Z]{2,})"; var regex = new RegExp("^(" + box1 + "|" + box2 + ")@(" + host1 + "|" + host2 + ")$");
sumber
Anda cukup menggunakan operasi string.
var pattenString = "^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|"+ "(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|"+ "(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$"; var patten = new RegExp(pattenString);
sumber
Saya mencoba meningkatkan jawaban korun dengan merangkum semuanya dan menerapkan dukungan untuk memisahkan kelompok penangkap dan kumpulan karakter - menjadikan metode ini jauh lebih serbaguna.
Untuk menggunakan cuplikan ini, Anda perlu memanggil fungsi variadic
combineRegex
yang argumennya adalah objek ekspresi reguler yang perlu Anda gabungkan. Implementasinya dapat ditemukan di bagian bawah.Grup penangkap tidak dapat dipisahkan secara langsung seperti itu karena akan meninggalkan beberapa bagian hanya dengan satu tanda kurung. Browser Anda akan gagal dengan pengecualian.
Sebagai gantinya saya hanya meneruskan konten dari grup penangkapan di dalam array. Tanda kurung secara otomatis ditambahkan saat
combineRegex
menemukan sebuah array.Selanjutnya pengukur perlu mengikuti sesuatu. Jika karena alasan tertentu ekspresi reguler perlu dipisahkan di depan pembilang, Anda perlu menambahkan sepasang tanda kurung. Ini akan dihapus secara otomatis. Intinya adalah bahwa grup tangkap kosong sangat tidak berguna dan dengan cara ini pembilang memiliki sesuatu untuk dirujuk. Metode yang sama dapat digunakan untuk hal-hal seperti grup non-capturing (
/(?:abc)/
menjadi[/()?:abc/]
).Ini paling baik dijelaskan menggunakan contoh sederhana:
var regex = /abcd(efghi)+jkl/;
akan menjadi:
var regex = combineRegex( /ab/, /cd/, [ /ef/, /ghi/ ], /()+jkl/ // Note the added '()' in front of '+' );
Jika Anda harus memisahkan kumpulan karakter, Anda bisa menggunakan objek (
{"":[regex1, regex2, ...]}
) daripada array ([regex1, regex2, ...]
). Isi kunci dapat berupa apa saja selama objek tersebut hanya berisi satu kunci. Perhatikan bahwa alih-alih()
Anda harus menggunakan]
permulaan dummy jika karakter pertama dapat diartikan sebagai pembilang. Yaitu/[+?]/
menjadi{"":[/]+?/]}
Berikut cuplikan dan contoh yang lebih lengkap:
function combineRegexStr(dummy, ...regex) { return regex.map(r => { if(Array.isArray(r)) return "("+combineRegexStr(dummy, ...r).replace(dummy, "")+")"; else if(Object.getPrototypeOf(r) === Object.getPrototypeOf({})) return "["+combineRegexStr(/^\]/, ...(Object.entries(r)[0][1]))+"]"; else return r.source.replace(dummy, ""); }).join(""); } function combineRegex(...regex) { return new RegExp(combineRegexStr(/^\(\)/, ...regex)); } //Usage: //Original: console.log(/abcd(?:ef[+A-Z0-9]gh)+$/.source); //Same as: console.log( combineRegex( /ab/, /cd/, [ /()?:ef/, {"": [/]+A-Z/, /0-9/]}, /gh/ ], /()+$/ ).source );
sumber
Jawaban hebat @ Hashbrown membuat saya berada di jalur yang benar. Ini versi saya, juga terinspirasi dari blog ini .
function regexp(...args) { function cleanup(string) { // remove whitespace, single and multi-line comments return string.replace(/\s+|\/\/.*|\/\*[\s\S]*?\*\//g, ''); } function escape(string) { // escape regular expression return string.replace(/[-.*+?^${}()|[\]\\]/g, '\\$&'); } function create(flags, strings, ...values) { let pattern = ''; for (let i = 0; i < values.length; ++i) { pattern += cleanup(strings.raw[i]); // strings are cleaned up pattern += escape(values[i]); // values are escaped } pattern += cleanup(strings.raw[values.length]); return RegExp(pattern, flags); } if (Array.isArray(args[0])) { // used as a template tag (no flags) return create('', ...args); } // used as a function (with flags) return create.bind(void 0, args[0]); }
Gunakan seperti ini:
regexp('i')` //so this is a regex //here I am matching some numbers (\d+) //Oh! See how I didn't need to double backslash that \d? ([a-z]{1,3}) /*note to self, this is group #2*/ `
Untuk membuat
RegExp
objek ini :/(\d+)([a-z]{1,3})/i
sumber