2011-06-15 3 views
1

Pouvez-vous s'il vous plaît m'aider à écrire une expression régulière pour cela.RegEx - S'il vous plaît aider à former ce RegEx

Name = "Windows Produit pour .Net"
type = "Programmation du logiciel"
Quantité = "Paquet de 3"

Je veux faire un match comme celui-ci en C# pour lequel j'ai besoin de RegEx.

If Name.contains(".Net") && (Type.Contains("Programming") || Type.Contains("Hardware") 
{ 
// output will be a Match. 
} 
else 
{ 
// no match. 
} 

L'approche que je veux prendre ici est, spécifier une expression régulière pour chaque condition, puis appliquer opérande logique & &, regroupement logique et opérande parenthèse logique ||. Je suis venu avec toutes les expressions régulières pour ceux-ci. Comment puis-je fournir des opérandes logiques pour chacun d'eux à exécuter dans l'ordre approprié?

string Name = "Windows Product for .Net"; 
    string Type = "Software Programming"; 

    string patternForName = ".*Net"; 
    Regex rgxName = new Regex(patternForName); 
    Match matchName = rgx.Match(Name); 
    string patternForType = ".*Programming"; 
    Regex rgxType = new Regex(patternForType); 
    Match matchType = rgx.Match(Type); 

    string patternForType1 = ".*Hardware"; 
    Regex rgxType1 = new Regex(patternForType1); 
    Match matchType1 = rgx.Match(Type); 

Veuillez noter - Nous le rendons dynamique, dans le sens où les motifs, opérandes et regEx proviennent du fichier xml. C'est pourquoi je ne veux pas écrire un gros regEx pour le dessus.

+1

Je ne suis pas sûr si quelque chose me manque, bien que dans votre exemple si tout votre utilisation est .Contains que RegEx ne serait pas nécessaire. Avez-vous des modèles plus complexes sur lesquels vous devez vous appuyer? – mservidio

Répondre

0

Il semble que vous vous demandiez comment gérer la partie logique du problème. Si vous l'extrayez d'un fichier xml, vous pouvez structurer votre fichier de la façon dont vous souhaitez structurer votre logique.

par exemple, ont Et et Ou groupes:

<And> 
    <Name Match=".Net"/> 
    <Or> 
     <Type Match="Programming"/> 
     <Type Match="Hardware"/> 
    </Or> 
</And> 

Créer des classes pour chacun de ces types. Par souci de concision, je ne ai pas définir les classes avec des propriétés ou créer des constructeurs, mais vous pouvez les remplir comme vous le voulez:

class YourType 
{ 
    string Name; 
    string Type; 
    string Quantity; 
} 

abstract class Test 
{ 
    public abstract bool RunTest(YourType o); 
} 

class AndTest : Test 
{ 
    public List<Test> Children; 
    public bool RunTest(YourType o) 
    { 
     foreach (var test in Children) 
     { 
     if (!test.RunTest(o)) return false; 
     } 
     return true; 
    } 
} 

class OrTest : Test 
{ 
    public List<Test> Children; 
    public bool RunTest(YourType o) 
    { 
     foreach (var test in Children) 
     { 
     if (test.RunTest(o)) return true; 
     } 
     return false; 
    } 
} 

class NameTest : Test 
{ 
    public string Match; 

    public bool RunTest(YourType o) 
    { 
     return o.Name.Contains(Match); 
    } 
} 

class TypeTest : Test 
{ 
    public string Match; 

    public bool RunTest(YourType o) 
    { 
     return o.Type.Contains(Match); 
    } 
} 

construire la structure de classe à partir du fichier xml et il suffit d'appeler RunTest du test de niveau supérieur. De cette façon, vous pouvez faire n'importe quel type de logique. J'ai juste utilisé Contains au lieu d'un Regex pour la facilité de l'exemple, mais vous pouvez facilement remplacer la correspondance de chaîne avec une correspondance regex.

+0

Ceci est très utile. Je peux construire un mécanisme générique :). Merci Mark. – user476566

0
if (rgxName.IsMatch(Name) && (rgxType.IsMatch(Type) || rgxType1.IsMatch(Type)) 
{ 
... 
} 
2

tout d'abord vous n'avez pas besoin d'un leader .* dans votre expression, sauf si vous voulez que le tout le match (à savoir lorsque l'on travaille avec des allumettes). Juste pour un simple "est-ce là" vous n'en aurez pas besoin car le motif pourrait correspondre à n'importe quelle position.

Il suffit d'utiliser une expression régulière pour chaque champ (c.-à-un pour Name, un pour Type, un pour Quantity:

string patternForName = "\\.Net"; // escaping the dot so it will match real dots only 
string patternForType = "Programming|Hardware"; // | will result in "left side or right side" 
string patternForQuantity = ".?"; // will match any string, even empty ones 

Pour vérifier tout:

bool match = rgxName.IsMatch(Name) && rgxType.IsMatch(Type) && rgx.IsMatch(Quantity); 
0

Dans .NET, Regex. Faites correspondre les correspondances n'importe où dans la chaîne, vous n'avez donc pas besoin du préfixe any-characters (. *) Sur votre modèle. Donc, pour vérifier ".NET", ce serait simplement:

Regex regexName = new Regex(@"\.NET", RegexOptions.IgnoreCase); 
// IsMatch returns true/false, Match returns a Match object 
bool nameMatches = regexName.IsMatch(name); 

Vos modèles de programmation et de matériel seraient tout

new Regex(@"Programming", RegexOptions.IgnoreCase) // Or leave out IgnoreCase if you're case-sensitive 
new Regex(@"Hardware") 

Si vous avez une liste de modèles de noms et une liste de modèles de type, vous pourriez faire quelque chose de similaire à ceci:

bool nameIsMatch = false; 
bool typeIsMatch = false; 

foreach (string namePattern in namePatterns) 
{ 
    nameIsMatch = nameIsMatch || Regex.IsMatch(nameString, namePattern); 
} 

foreach (string typePattern in typePatterns) 
{ 
    typeIsMatch = typeIsMatch || Regex.IsMatch(typeString, typePattern); 
} 

if (nameIsMatch && typeIsMatch) 
{ 
    // Whatever you want to do 
} 
1

Vous pouvez les rendre dynamiques sans utiliser regex. L'utilisation de regex ne vous fera pas gagner beaucoup de temps ou d'effort, puisque le code sera à peu près de la même taille. À la suite de votre schéma ci-dessus, vous pouvez faire quelque chose comme ceci:

var names = new[] { "Net", "Programming" }; 
var types = new[] { "Hardware" }; 

bool matchFound = true; 

foreach (string n in names) 
    matchFound &= Name.Contains(n); 

foreach (string t in types) 
    matchFound |= Type.Contains(t); 

Le code ci-dessus suppose que vous voulez faire correspondre tous les « noms » et l'un des « types », mais vous pouvez remplacer toute logique que vous voulez.

Le véritable noeud de votre problème est ces combinaisons booléennes; regex ne vous aidera pas dans la logique de ceux-ci, donc vous feriez mieux d'utiliser string.Contains à moins que les motifs que vous recherchez deviennent beaucoup plus variables. Regex vous distrait de votre véritable objectif ici, à mon avis.

0

patternForName = ".Net" patternForType = "Programmation" patternForType1 = "Matériel"

Vous trouverez peut-être Le Regex Coach pour être utile.

Questions connexes