comportement attendu de l'expression régulière posix extended: (() | abc) xyz

StackOverflow https://stackoverflow.com/questions/1436194

  •  07-07-2019
  •  | 
  •  

Question

Sur mon ordinateur OS X 10.5.8, l’utilisation des fonctions C de regcomp et de regexec pour faire correspondre la regex étendue & "(() | abc) xyz &"; je trouve une correspondance pour la chaîne < !> "abcxyz &"; mais seulement du décalage 3 au décalage 6. Mon espoir était que la chaîne entière serait mise en correspondance et que je verrais une sous-correspondance pour le & "; abc &"; partie de la chaîne.

Lorsque j'essaie le même motif et le même texte avec awk sur le même ordinateur, une correspondance est trouvée pour toute la chaîne, comme je le pensais.

Je m'attends à ce que mon expérience limitée avec les expressions régulières pose problème. Quelqu'un peut-il expliquer ce qui se passe? Mon expression régulière est-elle valide? Si oui, pourquoi ne correspond-il pas à la chaîne entière?

Je comprends que " ((abc) {0,1}) xyz " pourrait être utilisé comme alternative, mais le motif intéressant est généré automatiquement à partir d'un autre format de motif et élimine les occurrences de " () " C’est un travail supplémentaire que j’aimerais éviter si possible.

Pour référence, les indicateurs que je passe à regcomp consistent uniquement en REG_EXTENDED. Je passe un ensemble d'indicateurs vides (0) à regexec.

Était-ce utile?

La solution

Le POSIX indique:

  

9.4.3 Caractères spéciaux ERE

     

Un caractère spécial ERE a des propriétés spéciales dans certains contextes. En dehors de ces contextes ou précédé d'un <backslash>, un tel caractère doit être un ERE qui correspond au caractère spécial lui-même. Les caractères spéciaux de l'expression régulière étendue et les contextes dans lesquels ils auront une signification particulière sont les suivants:

     

.[\(

     

Les <period>, <left-square-bracket>, <left-parenthesis> et <right-parenthesis> doivent être spéciaux, sauf lorsqu'ils sont utilisés dans une expression entre crochets (voir RE Expression de crochet). En dehors d'une expression entre crochets, un () immédiatement suivi d'un <=> génère des résultats non définis.

Ce que vous voyez est le résultat de l'appel d'un comportement indéfini: tout est permis.

Si vous voulez des résultats fiables et transférables, vous devrez éliminer les notations "<=>" vides.

Autres conseils

Si vous parcourez toutes les correspondances et que vous n'obtenez pas les deux [3,6) et [0,6], il y a un bogue. Je ne suis pas sûr de ce que pose Posix en ce qui concerne l'ordre dans lequel les correspondances sont renvoyées.

Essayez (abc|())xyz - Je parie que cela produira le même résultat aux deux endroits. Je ne peux que présumer que la version C essaie d’adapter xyz partout où elle le peut, et si cela échoue, elle essaie d’adapter abcxyz partout où elle le peut (mais, comme vous le voyez, elle n’échoue pas, nous ne le ferons donc jamais. dérange avec la partie & "; abc &"; alors que awk doit utiliser son propre moteur regex qui fonctionne comme vous le souhaitez.

Votre expression régulière est valide. Je pense que le problème est soit: a) POSIX n’est pas très clair sur le fonctionnement de l’expression rationnelle, ou b) <=> n’utilise pas 100% de expressions rationnelles conformes à POSIX (probablement parce qu’il semble que OS X est livré avec une version plus originale de <=>). Quel que soit le problème, cela est probablement dû au fait qu'il s'agit d'un cas limite et que la plupart des gens n'écriraient pas l'expression rationnelle de cette façon.

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