2010-07-20 7 views
2

Je suis en train de valider par RegEx comme suit ...au regex "mot entier" retourne exception

If Regex.IsMatch(Output, "\b" & "Serial)" & "\b") Then 
'do something 
end if 

mais je reçois cette exception Argument

parsing "\bSerial)\b" - Too many)'s. 

Je comprends l'erreur, mais comment dois-je modifier l'expression RegEx?

MISE À JOUR. Le mot "Serial" est généré dynamiquement. Cela signifie au moins pour moi je pourrais obtenir une autre exception pour un autre personnage aussi.

Répondre

4

Paxdiablo et les réponses de tanascius expliquer correctement pourquoi votre regex ne parvient pas à compiler.

Mais:

Vous devez être prudent avec votre regex, même après avoir échappé à la parenthèse: \b correspond seulement à limites de mot (un mot étant construit à partir de caractères du \w raccourci - lettres, chiffres , et soulignent), pas après la ponctuation comme des parenthèses. Dans votre cas, la regex ne correspondra pas dans une chaîne comme foo Serial) bar. Il va correspondre dans foo Serial)bar, mais seulement parce que le \b correspond avantbar. De même, il ne correspondra pas à la chaîne Serial). Donc, entourer simplement une chaîne avec \b s ne fera pas toujours ce que vous attendez de lui.

Edit: Si, en fonction de votre commentaire ci-dessous, dans la liste suivante ...

foo Serial) bar 
foo (Serial) bar 
foo Serial). bar 
foo Serial)))))) 
foo Serial) 

... que la première et la cinquième doit correspondre, je déduis que la règle est de faire correspondre une mot entier seulement s'il est précédé/suivi d'un espace ou d'un début/fin de chaîne.

Dans ce cas, utilisez

If Regex.IsMatch(Output, "(?<=^|\s)" & Regex.Escape("Serial)") & "(?=\s|$)") Then 

Cependant, cela ne correspond plus aujourd'hui foo dans This is foo. ou He said "foo". Si vous voulez autoriser ceci, utilisez

If Regex.IsMatch(Output, "(?<=^|\b|\s)" & Regex.Escape("Serial)") & "(?=\s|\b|$)") Then 

... mais ceci correspondra maintenant au second exemple. Choisissez votre arme avec soin :)

(Explication: (?<=^|\b|\s) est une assertion lookbehind positive qui correspond s'il est possible de faire correspondre le début de la chaîne, une limite de mot ou un caractère d'espace avant la position actuelle, sans ajouter (?=\s|\b|$) est son homologue lookahead.)

+0

Je choisis le premier, et le cinquième! Merci Tim! – OrElse

+0

+1 pour aller plus loin - Je serais intéressé de voir la solution ... – paxdiablo

5

En supposant que VB.Net est, vous avez besoin d'échapper à la ):

If Regex.IsMatch(Output, "\b" & "Serial\)" & "\b") Then 
    'do something 
End If 

Dans les expressions régulières .Net, entre parenthèses sont les caractères de regroupement.


Si, comme vous le dites, le mot « série) » est généré dynamiquement, vous devrez escape avant de le transmettre au moteur RE:

If Regex.IsMatch(Output, "\b" & Regex.Escape("Serial)") & "\b") Then 
    'do something 
End If 

Comme un autre répondeur a posté, ceci ne correspondra pas "Serial) xyz" (par exemple) puisqu'il n'y a pas \b entre le ) et l'espace (\b seulement existe entre\w et \W caractères et les deux ) et un espace sont \W).

Vous pouvez avoir recours à une bidouille horrible comme:

If Regex.IsMatch(Output, "\s" & Regex.Escape("Serial)") & "\s") _ 
Or Regex.IsMatch(Output, "\s" & Regex.Escape("Serial)") & "$") _ 
Or Regex.IsMatch(Output, "^" & Regex.Escape("Serial)") & "\s") _ 
Or Regex.IsMatch(Output, "^" & Regex.Escape("Serial)") & "$") _ 
Then 
    'do something 
End If 

Je pensais que vous pourriez peut-être correspondre à une classe de caractères consistant en (^ ou $) et \s le long des lignes de:

If Regex.IsMatch(Output, "[\s^]" & Regex.Escape("Serial)") & "[\s$]") Then 
    'do something 
End If 

mais cela ne semble pas fonctionner basé sur le testeur de regex here de sorte que vous devrez peut-être opter pour la version hack laide ou vous pouvez les combiner en une seule regex comme dans:

var input = "Serial)" 
var escaped = Regex.Escape (input) 
var regex = "\s" & escaped & "\s|^" & escaped & "$|\s" & escaped & "$|^" & escaped & "\s" 
If Regex.IsMatch(Output, regex) Then 
    'do something 
End If 
+0

me battre à elle. : P +1 – falstro

+0

Pour plus de clarté, différentes expressions de regexp utilisent le groupement de différentes façons, posix regexp utilise '\\ (' et '\\)' pour le regroupement, perl regexps utilise simplement '(' et ')' et utilise '\ \ ('et' \\) 'signifient les parenthèses littérales. – falstro

+0

Je suppose que je vais devoir éditer la question. Le mot Serial) est généré dynamiquement – OrElse

0

Je pense que ce dont vous avez besoin peut être

\bSerial\)\b 

(c'est "\ b" & "série)" & "\ b")

1

Vous devez échapper à votre entrée en utilisant Regex.Escape() :

String input = "Serial)"; 
If Regex.IsMatch(Output, "\b" & Regex.Escape(input) & "\b") Then 
    'do something 
end if 
0

Vous devez échapper les parenthèses.c'est) avec) Ainsi, la chaîne finale devrait ressembler, \ bSerial) \ b

Si le contenu génère de façon dynamique, recherche « (» et «) » et les remplacer par le caractère d'échappement approprié (juste un remplacement de chaîne!) à "(" et ")" ou utilisez Regex.Escape() pour échapper ces caractères!

HTH