6
votes

Expressions régulières - C # se comporte différemment que Perl / Python

sous Python:

$ csc regexp.cs
Microsoft (R) Visual C# 2008 Compiler version 3.5.30729.5420
for Microsoft (R) .NET Framework version 3.5
Copyright (C) Microsoft Corporation. All rights reserved.

$ ./regexp.exe 
GeorgeGeorge


2 commentaires

Je pense que la réponse est que chaque langue a sa propre mise en œuvre d'expressions régulières. Par conséquent, une regex se comportera différemment selon laquelle le moteur est exécuté.


+1 pour la compilation de ligne de commande.


4 Réponses :


2
votes

Ce n'est pas clair pour moi, qu'il s'agisse d'un bug ou non, mais si vous modifiez le . * code> à . + code> Cela fait ce que vous voulez. Je soupçonne que c'est le fait que (. *) Code> correspond à une chaîne vide qui est confuse de choses.

Ceci est sauvegardé par le code suivant: p>

using System;
using System.Text.RegularExpressions;

class Test
{
    static void Main()
    {
        var match = Regex.Match("abc", "(.*)");
        while (match.Success)
        {
            Console.WriteLine(match.Length);
            match = match.NextMatch();
        }
    }
}


0 commentaires

2
votes

Le remplacement de "" est "george" (. * correspondre ) ) et xxx

de sorte que la regex correspond à "ceci est un démarrage" et le remplace par "george" , et maintenant Son "curseur" est à la fin de la chaîne, où il essaie de faire correspondre la chaîne restante ( "" ) avec le motif. Il a une correspondance pour qu'il ajoute un deuxième "george" . Je ne sais pas si cela est correct ou non.

Je vais ajouter que le moteur JavaScript semble faire la même chose (testée ici: http://www.regular-expressions.info/javascriptexample.html ) sous IE et chrome.


1 commentaires

Je crois que c'est en fait la position de départ causant la question. Il est résolu si vous modifiez la regex vers ^ (. *)



2
votes

est-ce un bug dans la bibliothèque d'expression régulière de C #

Peut-être, mais cela ne vous répond pas vraiment:

expressions régulières - C # se comporte différemment de Perl / Python

Différents moteurs d'expression réguliers et implémentations se comportent différemment. Parfois, cela explicite (et comprend des éléments d'expression réguliers différents et de la syntaxe: par exemple. Utilisation d'un \ ( et \ \) pour grouper plutôt que par des parenthèses avec une barre oblique inverse du regroupement).

Le livre maîtrise des expressions régulières (Jeffrey ef Friedl, O'Reilly ) passe beaucoup de temps à expliquer ces différences (au-dessus des différences plus fondamentales entre les approches non déterministes d'automates finis (NFA) et de l'automate (DFA) déterministiques).

ps. Comme les autres notent . * correspond à la chaîne vide, la première version "TOUT" est donc appariée et remplacée, la chaîne vide à la fin de l'entrée est assortie et remplacée. Si vous voulez correspondre à l'ensemble, mais éventuellement vide, l'entrée comprend des ancrages pour le début et la fin: ^ (. *) $ . .


0 commentaires

6
votes

Dans votre exemple, la différence semble être dans la sémantique de la fonction "Remplacer" plutôt que dans le traitement d'expression régulier lui-même.

.NET fait un "global" remplacer, c'est-à-dire qu'il remplace toutes les correspondances plutôt que Juste la première match.

Remplacer global dans Perl

( remarque le petit "g" à la fin de la ligne = / em>) xxx

qui produit xxx

simple remplacement de .NET xxx

qui produit xxx

puisqu'il s'arrête après le premier remplacement.


1 commentaires

+1 Droite! Il peut le voir très facilement: $ a = ~ s /(.)/ x /; donne xhis est un test sous Perl.