views:

60

answers:

3

I have a long string (8000 characters) that should contain only hexadecimal and newline characters.

What is the best way to validate / verify that the string does not contain invalid characters?

Valid characters are: 0 through 9 and A through F. Newlines should be acceptable.

I began with this code, but it does not work properly (i.e. fails to return false when a "G" is the first character):

public static bool VerifyHex(string _hex)
{
    Regex r = new Regex(@"^[0-9A-F]+$", RegexOptions.Multiline);
    return r.Match(_hex).Success;
}
+1  A: 

You're misunderstanding the Multiline option:

Use multiline mode, where ^ and $ match the beginning and end of each line (instead of the beginning and end of the input string).

Change it to

static readonly Regex r = new Regex(@"^[0-9A-F\r\n]+$");
public static bool VerifyHex(string _hex)
{
    return r.Match(_hex).Success;
}
SLaks
@SLaks, thank you, this worked as needed. I was using the Multiline option incorrectly (much like using a screwdriver for a chisel, one achieves less-than-great results).
JYelton
+1  A: 

Another option, if you fancy using LINQ instead of regular expressions:

public static bool IsHex(string text)
{
    return text.All(IsHexChar); 
}

private static bool IsHexCharOrNewLine(char c)
{
    return (c >= '0' && c <= '9') ||
           (c >= 'A' && c <= 'F') ||
           (c >= 'a' && c <= 'f') ||
           c == '\n'; // You may want to test for \r as well
}

Or:

public static bool IsHex(string text)
{
    return text.All(c => "0123456789abcdefABCDEF\n".Contains(c)); 
}

I think a regex is probably a better option in this case, but I wanted to just mention LINQ for the sake of interest :)

Jon Skeet
I am using and liking LINQ more every day. This reads cleanly but would regex perform better?
JYelton
@JYelton: I don't know - why don't you benchmark it with some real data and check? I'd expect the first version to run faster than the second, mind you.
Jon Skeet
A: 

There are already some great answers but no one has mentioned using the built in parsing which seems to be the most straight forward way:

public bool IsHexString(string hexString)
{
    System.Globalization.CultureInfo provider = new System.Globalization.CultureInfo("en-US");
    int output = 0;
    return Int32.TryParse(hexString, System.Globalization.NumberStyles.HexNumber, provider, out output))
}    
Kelsey
The strings I am testing are ~8000 characters, it would overflow Int32 unless broken into pieces.
JYelton
@JYelton somehow I missed that in the question sorry. Well at least this is a good conversion for anyone else that needs to do a lot less chars :)
Kelsey