tags:

views:

71

answers:

2

I have the problem that I can only use one Regex.IsMatch to validate a string and I have to conditions with regular expressions to be matched for the same string, I've looking and seems that I can use regex conditionals like (?(?=regex)then|else) to match both regular expressions on the string value, but I can't reach the same result

My actual code working with two regular expressions validation is:

bool flag = false;
if (Regex.IsMatch(alias, "^[a-zñA-ZÑ_0-9-.]{6}[a-zñA-ZÑ_0-9-.]*$")) 
{
    if (Regex.IsMatch(alias, "[^0-9.-]+"))
    {
        flag = true;
    };
};

And what i want to achieve is something like this:

if (Regex.IsMatch(alias, "(?(^[a-zñA-ZÑ_0-9-.]{6}[a-zñA-ZÑ_0-9-.]*$)([^0-9.-]+))"))
{
    // Some code...
};

so if you can give me some guidance or check if my regular expression is right using the conditional in regexp it would appreciated

+2  A: 

Your first regexp:

^[a-zñA-ZÑ_0-9-.]{6}[a-zñA-ZÑ_0-9-.]*$

says that 0-9.- is allowed, while the second one says 0-9.- is not allowed. Why not just change the first one to:

^[a-zñA-ZÑ_]{6}[a-zñA-ZÑ_]*$

and even simpler:

^[a-zñA-ZÑ_]{6,}$

since both parts are equal

[Edit - code sample]

Alan's answer is probably the most elegant, but you could also achieve it like this:

bool flag = false;
Match m = Regex.Match(alias, "(?<main>^[a-zñA-ZÑ_0-9-.]{6,}$)|(?<char>[^0-9.-])");
if (m.Groups["main"].Success && m.Groups["char"].Success)
{
    flag = true;
};

That said, it's often better to break up a regular expression into several parts imo. It makes it more readable, and each expression does one thing. As long as you're not executing the expression a million times a second the overhead of running several Regexp's is minuscule.

Mikael Svenson
thanks for helping, the fact is that the string I'm parsing can have numbers, but I must validate that it has at least one char that isn't a number, and thanks for the simplifier regexp
David
@Mikael: When the second regex is applied, the string has already been matched by the first, so `[^0-9.-]+` just ensures that at least one of the characters in the string is a letter or underscore rather than a digit, dot or dash.
Alan Moore
@alan: true. I will fix my answer once i get to a computer. Writing code on my mobile is cumbersome.
Mikael Svenson
+1  A: 

What you need is a lookahead, not a conditional. Observe:

^(?=.*[a-zñA-ZÑ_])[a-zñA-ZÑ_0-9.-]{6,}$

The lookahead - (?=.*[a-zñA-ZÑ_]) - asserts that there is at least one of the listed characters somewhere in the string. When it's done, the match position returns to the beginning of the string so the "real" regex can match the whole thing.

For more information about lookaheads: http://www.regular-expressions.info/lookaround.html

Alan Moore