Question

Comment peut-on écrire une expression régulière qui correspond à un modèle qui peut contenir des citations, mais si elle le fait, doit avoir au correspondant devis début et à la fin?

"?(pattern)"?

ne fonctionnera pas, car il permettra à des modèles qui commencent par une citation, mais ne se termine pas avec un.

"(pattern)"|(pattern)

fonctionnera, mais est répétitif. Y at-il une meilleure façon de le faire sans répéter le motif?

Était-ce utile?

La solution

Vous pouvez obtenir une solution sans répéter en utilisant et des backreferences conditionals:

/^(")?(pattern)(?(1)\1|)$/

Correspondances:

    motif
  • "modèle"

Ne correspond pas à:

  • "modèle
  • modèle
  • "

Ce modèle est un peu complexe, cependant. Il recherche d'abord un devis en option, et la met en backreference 1 si l'on se trouve. Ensuite, il recherche votre modèle. Ensuite, il utilise une syntaxe conditionnelle de dire « si backreference 1 se trouve à nouveau, il correspond, sinon rien correspondre ». Le schéma entier est ancré (ce qui signifie qu'il doit apparaître seul sur une ligne) de sorte que des guillemets non ne seront pas capturées (sinon le pattern dans pattern" égalerait).

Notez que le support pour conditionals varie selon le moteur et le plus bavard, mais les expressions répétitives seront plus largement pris en charge (et probablement plus facile à comprendre).


Mise à jour: Une version beaucoup plus simple de cette regex serait /^(")?(pattern)\1$/, qui n'a pas besoin d'une condition. Quand je testais ce premier temps, le testeur que j'utilisais m'a donné un faux négatif, ce qui me conduit à une réduction, il (oups!).

Je vais laisser la solution avec la mise sous condition pour la postérité et de l'intérêt, mais cela est une version plus simple qui est plus susceptible de travailler dans une plus grande variété de moteurs (sont la seule des backreferences fonction utilisée ici, qui pourrait être non pris en charge) .

Autres conseils

En fonction de la langue que vous utilisez, vous devriez être en mesure d'utiliser des références arrières. Quelque chose comme ça, dire:

(["'])(pattern)\1|^(pattern)$

De cette façon, vous êtes exigeant que soit il n'y a pas de guillemets, ou que la citation SAME utilisée sur les deux extrémités.

Cela devrait fonctionner avec regex récursive (qui a besoin de plus pour obtenir le droit). En attendant: Perl , vous pouvez construire une automodifiant regex . Je vais laisser cela comme un exemple académique; -)

my @stuff = ( '"pattern"', 'pattern', 'pattern"', '"pattern'  );

foreach (@stuff) {
   print "$_ OK\n" if /^
                        (")?
                        \w+
                        (??{defined $1 ? '"' : ''})
                       $
                      /x
}

Résultat:

"pattern" OK
pattern OK
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top