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;
}
8
  • 2
    Your Regex should be static.
    – SLaks
    Commented Sep 8, 2010 at 16:51
  • Looks like a repost of: stackoverflow.com/questions/223832/…
    – Rudu
    Commented Sep 8, 2010 at 16:52
  • Did you test how/why it doesn't work? Now we need to guess what's wrong here.. Commented Sep 8, 2010 at 16:53
  • @Rudi: It is similar but mine must allow newlines.
    – JYelton
    Commented Sep 8, 2010 at 16:59
  • 1
    @Sander Rijken: Yes, but SLaks identified the reason. The Multiline option was causing it to match based on lines that were correct. A "G" appearing on the first line was merely ignored. Because other lines matched, it reported true.
    – JYelton
    Commented Sep 8, 2010 at 17:06

3 Answers 3

5

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 :)

3
  • I am using and liking LINQ more every day. This reads cleanly but would regex perform better?
    – JYelton
    Commented Sep 8, 2010 at 17:02
  • @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
    Commented Sep 8, 2010 at 17:18
  • I performance tested this compared to the Regular Expression solution, and this approach is ~3x faster. Commented Jun 12, 2017 at 18:54
3

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;
}
1
  • 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
    Commented Sep 8, 2010 at 17:08
1

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))
}    
2
  • 1
    The strings I am testing are ~8000 characters, it would overflow Int32 unless broken into pieces.
    – JYelton
    Commented Sep 8, 2010 at 17:11
  • @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
    Commented Sep 8, 2010 at 17:13

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.