189 votes

Comment diviser une longue expression régulière en plusieurs lignes en JavaScript ?

J'ai une expression régulière très longue, que je souhaite diviser en plusieurs lignes dans mon code JavaScript afin de conserver une longueur de 80 caractères pour chaque ligne, conformément aux règles de JSLint. C'est tout simplement mieux pour la lecture, je pense. Voici un exemple d'expression régulière :

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,}))$/;

6voto

Anvesh Reddy Points 111

La regex ci-dessus manque des slashs noirs, ce qui ne fonctionne pas correctement. Donc, j'ai modifié la regex. Veuillez considérer cette expression qui fonctionne à 99,99% pour la validation des emails.

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(''));

2voto

andreasonny83 Points 726

Pour éviter l'Array join vous pouvez également utiliser la syntaxe suivante :

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,}))$');

2voto

Mubeena Points 21

Vous pouvez simplement utiliser une opération de type chaîne.

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);

2voto

Scindix Points 438

J'ai essayé d'améliorer la réponse de korun en encapsulant tout et en implémentant la prise en charge de la division des groupes de capture et des jeux de caractères - ce qui rend cette méthode beaucoup plus polyvalente.

Pour utiliser cet extrait, vous devez appeler la fonction variadique combineRegex dont les arguments sont les objets d'expression régulière que vous devez combiner. Son implémentation se trouve en bas de page.

Les groupes de capture ne peuvent cependant pas être divisés directement de cette manière, car certaines parties ne comporteraient qu'une seule parenthèse. Votre navigateur échouerait avec une exception.

Au lieu de cela, je passe simplement le contenu du groupe de capture dans un tableau. Les parenthèses sont automatiquement ajoutées lorsque combineRegex rencontre un tableau.

De plus, les quantificateurs doivent suivre quelque chose. Si, pour une raison quelconque, l'expression régulière doit être divisée devant un quantificateur, vous devez ajouter une paire de parenthèses. Celles-ci seront supprimées automatiquement. Le fait est qu'un groupe de capture vide est plutôt inutile et que, de cette façon, les quantificateurs ont quelque chose à quoi se référer. La même méthode peut être utilisée pour des choses comme les groupes de non-capture ( /(?:abc)/ devient [/()?:abc/] ).

La meilleure façon de l'expliquer est d'utiliser un exemple simple :

var regex = /abcd(efghi)+jkl/;

deviendrait :

var regex = combineRegex(
    /ab/,
    /cd/,
    [
        /ef/,
        /ghi/
    ],
    /()+jkl/    // Note the added '()' in front of '+'
);

Si vous devez diviser les jeux de caractères, vous pouvez utiliser des objets ( {"":[regex1, regex2, ...]} ) au lieu de tableaux ( [regex1, regex2, ...] ). Le contenu de la clé peut être n'importe quoi, tant que l'objet ne contient qu'une seule clé. Notez qu'au lieu de () vous devez utiliser ] comme début fictif si le premier caractère peut être interprété comme un quantificateur. C'est-à-dire /[+?]/ devient {"":[/]+?/]}

Voici l'extrait et un exemple plus complet :

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
);

1voto

Nuno Cruces Points 71

@Hashbrown's great réponse m'a mis sur la bonne voie. Voici ma version, également inspirée par ceci blog .

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]);
}

Utilisez-le comme ça :

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*/
`

Pour créer cette RegExp objet :

/(\d+)([a-z]{1,3})/i

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X