Grâce au monde merveilleux de littéraux de modèle vous pouvez désormais écrire de gros articles, sur plusieurs lignes et bien commentés, et même sémantiquement imbriqués regex 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 ceci, vous pouvez maintenant écrire des regex comme ceci :
let re = regex`I'm a special regex{3} //with a comment!`;
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é !
"Et si j'avais besoin de rechercher une nouvelle ligne ? \n
idiot !
Cela fonctionne sur mon Firefox et mon Chrome.
Ok, "que diriez-vous de quelque chose d'un peu plus complexe ?"
Bien sûr, voici un morceau d'un analyseur JS de déstructuration 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 produit /^\s*((\})|(?:[,{]\s*)(?:(\.\.\.)|(\b\d+\b|\b[A-Za-z$_][\w$]*\b|("|')(?:(?!\5|\\).|(?:\\.))*\5)\s*(:|)|\s*(?={)))((?:\s*(?:[,}\]=]|$)|\s*\}|\s*[{[:]|\s*[,}{]).*)$/
Et le faire fonctionner 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 réussies
{why
, hello
, there
, "you huge \""
, 17
,
{big
,smelly
}
}
Notez la capture réussie de la chaîne de caractères citée.
Je l'ai testé sur Chrome et Firefox, il fonctionne à merveille !
Si <a href="https://stackoverflow.com/a/60026664/2518317">curieux vous pouvez vérifier ce que je faisais </a>y <a href="https://jsfiddle.net/anmb03jf/" rel="noreferrer">sa démonstration </a>.<br>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 édulcorée et qu'il peut facilement se faire piéger en acceptant des chaînes de caractères invalides.