1

I have a TextBox where I want to let users enter hexadecimal values (excluding the 0x prefix) in a comma separated list. The problem is that I only want each value to be a length of four characters. Following this answer, I use the KeyPress event handler to do this check that the user can only enter a digit:

private void filterIDTextBox_KeyPress(object sender, KeyPressEventArgs e)
{
    if (!Char.IsControl(e.KeyChar) && !Char.IsDigit(e.KeyChar))
    {
        e.Handled = true;
    }
}

With Regex, we can restrict the user even more to only allow 0-9, A-F, a-f, and comma like this:

private void filterIDTextBox_KeyPress(object sender, KeyPressEventArgs e)
{
    if (!Char.IsControl(e.KeyChar) && !Regex.IsMatch(e.KeyChar.ToString(), "[0-9A-Fa-f,]"))
    {
        e.Handled = true;
    }
}

Is there any way I can use regex to make sure there are no more than 4 characters in between each comma? I tried using "[0-9A-Fa-f,]{0:4}" but this didn't work because I am doing the match only on the char, not the TextBox's text.

With that, I'm sure I'll have to use something other than KeyPress, but I still have been unsuccessful in writing the Regex statement for only allowing values up to 4 characters.

Community
  • 1
  • 1
AdamMc331
  • 16,492
  • 10
  • 71
  • 133
  • @juharr which event is best to do that in? TextChanged? – AdamMc331 Sep 21 '15 at 18:06
  • You can still use `KeyPress`, just instead of `e.KeyChar.ToString` use `filterIDTextBox.Text`. – juharr Sep 21 '15 at 18:07
  • Could you please provide/describe a use case? – Wiktor Stribiżew Sep 21 '15 at 18:08
  • @stribizhev An example would be the user entering "1234,1234,12345,1234", that third item is invalid because it shouldn't be more than four chars. – AdamMc331 Sep 21 '15 at 18:10
  • You can use `^[0-9A-Fa-f]{1,4}(?:,[0-9A-Fa-f]{1,4})+$` regex to do that validation done on the whole string. It assumes that the values between commas can have 1 to 4 symbols. Have a look [here](https://regex101.com/r/gX7mJ6/1) – Wiktor Stribiżew Sep 21 '15 at 18:12
  • @stribizhev Yes, I did, but I can still enter values larger than 4 characters. – AdamMc331 Sep 21 '15 at 18:21
  • @stribizhev I can go to the textbox and begin typing '123456...' but was hoping it'd stop me after '1234' until I insert a comma, because the pattern no longer matches. – AdamMc331 Sep 21 '15 at 18:23

1 Answers1

3

First you need to validate the entire text for this to work so validate filterIDTextBox.Text plus the key that was pressed. Second you need a regular expression that validates the entire field.

private void filterIDTextBox_KeyPress(object sender, KeyPressEventArgs e)
{
    string newValueIfAllowed = filterIDTextBox.Text + e.KeyChar.ToString();
    if (!Char.IsControl(e.KeyChar) 
        && (!Regex.IsMatch(e.KeyChar.ToString(), "[0-9A-Fa-f,]")
        || !Regex.IsMatch(newValueIfAllowed , "^([0-9A-Fa-f]{1,4},)*[0-9A-Fa-f]{0,4}$")))
    {
        e.Handled = true;
    }
}

That will allow any number of 1 to 4 digit hex values followed by a comma then followed by 0 to 4 more hex digits. That means that 123,456, is valid, but you need that to be valid to allow the user to type in the comma and continue.

An alternative is to wait and validate after the user enters a value and presses some type of submit button. Then you could change the expression to not allow blank values or trailing commas by changing the {0,4} to {1,4}.

Note: this assumes the user only types characters at the end of the text box if they move the cursor around you'll have to take that into account. Also selecting text and replacing it and copy-and-paste actions would also be problematic.

juharr
  • 31,741
  • 4
  • 58
  • 93
  • I think inside the curly brackets you use a comma to represent the range, don't you? `{1,4}` for example. Either way, still not having success but I will try to figure out why. Using this code: `if (!Char.IsControl(e.KeyChar) && !Regex.IsMatch(e.KeyChar.ToString(), "[0-9A-Fa-f,]") && !Regex.IsMatch(filterIDTextBox.Text, "([0-9A-Fa-f]{1,4},)*[0-9A-Fa-f]{0,4}"))` the textbox is letting me enter non-hex characters. Not sure what I'm missing, yet. – AdamMc331 Sep 21 '15 at 18:19
  • ^I think the reason I was allowed to type non-hex characters was because of the asterisk. I removed that, but can still enter values with more than 4 digits. – AdamMc331 Sep 21 '15 at 18:19
  • Yes, it's comma, not dash for the range. The asterisk alone should not allow you to enter any character. In fact your first regular expression on the character should block any non hex or comma characters. Though I was missing anchors. – juharr Sep 21 '15 at 18:23
  • Well, if I type an 'O' for example, the first condition is true, the second condition is true, but the third condition is false therefore it doesn't get rejected. Perhaps my conditions are wrong? – AdamMc331 Sep 21 '15 at 18:24
  • Yeah if you want all three you need to or instead of and. I'll update though technically you don't need to validate the single character anymore. – juharr Sep 21 '15 at 18:26
  • I'll give it a shot without the second condition, like you have it. – AdamMc331 Sep 21 '15 at 18:27
  • You might also have to add the character to the end of the text to test what might be as I don't think the text box value is updated until after the key press event. – juharr Sep 21 '15 at 18:30
  • You are right that it is not updated until after. I am very close, this does the proper validation but allows me to type up to 5 characters and if I do it then rejects the next comma because I've broken the pattern. I have enough to keep playing with this, and once I get it secure I will let you know. +1 for now, thank you so much. – AdamMc331 Sep 21 '15 at 18:31
  • FYI, I updated to fix the issue of the text not including the key that was just pressed. – juharr Sep 21 '15 at 18:33
  • This is interesting. It works, if I had {0,4} characters I can add a comma after. However, it lets me type 5 characters, and then I can't type anything at all. I'm struggling to figure out why it allows the fifth character, that must be because it's called before the text actually changes. – AdamMc331 Sep 21 '15 at 18:37
  • What if you concatenate the key to the end of the text then test that? – juharr Sep 21 '15 at 18:39
  • I cannot believe I didn't think of that. It works! I will spend my own time seeing if I can get rid of one of the conditions and just do one regex check, but if I can't get it I won't stress because this works. Thank you so so much! – AdamMc331 Sep 21 '15 at 18:42
  • You also need to check the position of the cursor in the text box to make sure you add the character to the correct position. Right now it assumes the cursor is always at the end. Also you might need to tweak this if the user highlights text and starts typing or does a copy paste. – juharr Sep 21 '15 at 18:43
  • Right. I can move forward with that, though. The regex to look for the 0-4 characters followed by a comma is what I was struggling to write. I can handle the key placement. Thanks again! – AdamMc331 Sep 21 '15 at 18:44