web-dev-qa-db-fra.com

Que signifie (^?) * Dans cette expression régulière?

J'ai cette expression régulière:

^(^?)*\?(.*)$

Si je comprends bien, voici la répartition de ce qu'il fait:

  • ^ - commence la correspondance depuis le début de la chaîne
  • (^?) * - Je ne sais pas, mais il le stocke dans 1 $
  • \? - correspond à un point d'interrogation
  • (. *) $ - correspond à tout jusqu'à la fin de la chaîne

Alors, que signifie (^?) *?

19
doremi

Le (^?) recherche simplement le caractère littéral ^. Le ^ le caractère d'un modèle d'expression régulière n'a une signification spéciale que lorsqu'il est utilisé comme premier caractère du modèle ou comme premier caractère d'une correspondance de regroupement []. Lorsqu'il est utilisé en dehors de ces 2 positions, le ^ est interprété littéralement dans les recherches de ^ caractère dans la chaîne d'entrée

Remarque: si oui ou non ^ en dehors de la première position et le regroupement est interprété littéralement comme étant un moteur d'expression régulière. Je ne connais pas assez bien le LUA pour dire ce qu'il fait

21
JaredPar

Lua n'a pas de langage regexp conventionnel, il a des modèles Lua à sa place. Bien qu'ils ressemblent beaucoup à l'expression rationnelle, les modèles Lua sont un langage distinct qui leur est propre, qui a un ensemble de règles plus simple et, surtout, manque de fonctionnalités de regroupement et d'alternance.

Interprété comme un modèle Lua, l'exemple surprendra un utilisateur de regexp de longue date car tant de détails sont différents.

Les modèles Lua sont décritsinPiL , et à première vue sont suffisamment similaires à une expression rationnelle conventionnelle pour créer de la confusion. Les plus grandes différences sont probablement le manque d'un opérateur d'alternance |, Les parenthèses ne sont utilisées que pour marquer les captures, les quantificateurs (?, -, + Et *) S'applique uniquement à un caractère ou à une classe de caractères, et % Est le caractère d'échappement et non \. Un grand indice que cet exemple n'a probablement pas été écrit en pensant à Lua est le manque du caractère citant le motif Lua % Appliqué à n'importe lequel (ou idéalement, tous) des caractères non alphanumériques de la chaîne de motif, et l'utilisation suspecte de \? qui sent comme une expression régulière pour correspondre à un seul littéral ?.

La réponse simple à la question posée est: (^?)* N'est pas un formulaire recommandé et correspondrait à ^* Ou *, Capturant la présence ou l'absence du curseur. Si tel était l'effet recherché, je l'écrirais sous la forme (%^?)%* Pour rendre cela plus clair.

Pour voir pourquoi c'est le cas, prenons le modèle donné et analysons-le comme un modèle Lua. Le motif entier est:

^(^?)*\?(.*)$

Remis à string.match(), il serait interprété comme suit:

^ Ancre la correspondance au début de la chaîne.

( Marque le début de la première capture.

^ N'est pas au début du modèle ou d'une classe de caractères, il correspond donc à un caractère ^ Littéral. Pour plus de clarté, cela aurait probablement dû être écrit comme %^.

? Correspond exactement à zéro ou à l'un des caractères précédents.

) Marque la fin de la première capture.

* N'est pas après quelque chose qui peut être quantifié, il correspond donc à un caractère * Littéral. Pour plus de clarté, cela aurait probablement dû être écrit comme %*.

\ Dans un modèle correspond à lui-même, ce n'est pas un caractère d'échappement dans le langage de modèle. Cependant, il est un caractère d'échappement dans un littéral de chaîne courte Lua, ce qui rend le caractère suivant non spécial pour l'analyseur de littéral de chaîne qui dans ce cas est théorique car le ? Qui suit ne lui était pas spéciale en tout cas. Donc, si le modèle était placé entre guillemets doubles ou simples, le \ Serait absorbé par l'analyse de chaîne. Si elle est écrite dans une longue chaîne (comme [[^(^?)*\?(.*)$]], la barre oblique inverse survivrait à l'analyseur de chaîne, pour apparaître dans le modèle.

? Correspond exactement à zéro ou à l'un des caractères précédents.

( Marque le début de la deuxième capture.

. Correspond à n'importe quel caractère, en fait un synonyme de la classe [\000-\255] (Rappelez-vous, dans Lua, les échappements numériques sont en décimal et non en octal comme en C).

* Correspond à zéro ou plus du caractère précédent, avec avidité.

) Marque la fin de la deuxième capture.

$ Ancre le motif à la fin de la chaîne.

Ainsi, il correspond et capture un ^ Facultatif au début de la chaîne, suivi de *, Puis un \ Facultatif qui n'est pas capturé et capture le reste de la chaîne. chaîne. string.match Renverrait deux chaînes en cas de succès (l'une ou les deux étant de longueur nulle), ou nil en cas d'échec.

Edit: J'ai corrigé quelques fautes de frappe, et corrigé une erreur dans ma réponse, remarquée par Egor dans un commentaire. J'ai oublié que dans les motifs, les symboles spéciaux perdent leur particularité lorsqu'ils se trouvent dans un endroit où ils ne peuvent pas s'appliquer. Cela fait que le premier astérisque correspond à un astérisque littéral plutôt qu'à une erreur. La cascade de cela passe par la plupart des réponses.

Notez que si vous voulez vraiment une vraie expression rationnelle dans Lua, il existe des bibliothèques disponibles qui le fourniront. Cela dit, le langage de modèle intégré est assez puissant. Si cela ne suffit pas, il vaut mieux adopter un analyseur complet et utiliser LPeg qui peut faire tout ce qu'une expression rationnelle peut faire et plus encore. Il est même livré avec un module qui fournit une syntaxe regexp complète qui est traduite dans une grammaire LPeg pour exécution.

7
RBerteig

Dans ce cas, le (^?) Fait référence à la chaîne précédente "^" qui signifie le caractère littéral ^ comme l'a dit Jared. Consultez regexlib pour tout déchiffrement supplémentaire.

Pour tous vos besoins Regex: http://regexlib.com/CheatSheet.aspx

2
Tui Popenoe

Il me semble que l'intention du créateur de l'expression était de faire correspondre n'importe quel nombre de ^ avant le point d'interrogation, mais voulait seulement capture la première instance de ^. Cependant, cela peut ne pas être une expression valide selon le moteur, comme d'autres l'ont dit.

1
adam0101