Grâce au monde merveilleux des modèles littéraux, vous pouvez désormais écrire de grandes expressions rationnelles multi-lignes, bien commentées et même imbriquées sémantiquement dans 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])
))
);
En utilisant cela, vous pouvez maintenant écrire des expressions régulières comme ceci:
let re = regex`I'm a special regex{3} //with a comment!`;
Les sorties
/I'm a special regex{3}/
Ou qu'en est-il de la multiligne?
'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]
Sorties hel
, soignées!
"Et si j'ai besoin de rechercher une nouvelle ligne?", Eh bien, utilisez \n
idiot!
Travailler sur mon Firefox et Chrome.
Ok, "que diriez-vous de quelque chose d'un peu plus complexe?"
Bien sûr, voici un morceau d'un analyseur JS de destruction d'objet sur lequel je travaillais :
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*[,}{]
).*)
$`
Il sort /^\s*((\})|(?:[,{]\s*)(?:(\.\.\.)|(\b\d+\b|\b[A-Za-z$_][\w$]*\b|("|')(?:(?!\5|\\).|(?:\\.))*\5)\s*(:|)|\s*(?={)))((?:\s*(?:[,}\]=]|$)|\s*\}|\s*[{[:]|\s*[,}{]).*)$/
Et l'exécuter avec une petite démo?
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]);
Sorties avec succès
{why
, hello
, there
, "you huge \""
, 17
,
{big
,smelly
}
}
Notez la capture réussie de la chaîne entre guillemets.
Je l'ai testé sur Chrome et Firefox, ça marche un régal!
Si vous êtes curieux, vous pouvez consulter ce que je faisais et sa démonstration .
Bien que cela ne fonctionne que sur Chrome, car Firefox ne prend pas en charge les références arrière ou les groupes nommés. Notez donc que l'exemple donné dans cette réponse est en fait une version stérilisée et pourrait facilement être amené à accepter des chaînes invalides.
/\S+@\S+\.\S+/
?