简体   繁体   中英

RegEx pattern two letters or digits followed by digits

could you please help me to build proper regex? It should be 2 letters or digits followed with digits.

These would be valid: 
AA00
AB12
A123
1234

These would not
1DAA
D1D2
DDDD

Here is my code sample

public void installFilterOnlyNumberAndLetters(final TextField tf) {
tf.textProperty().addListener(new ChangeListener<String>() {
  @Override
  public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
    if (newValue != null && !newValue.matches("(([A-Z][A-Z0-9])||([A-Z][A-Z])|(|\\d\\d))\\d+")) {
      tf.setText(newValue.replaceAll("[^(([a-z][a-z0-9])||([a-z][a-z])|(|\\d\\d))\\d+]", ""));
    }
  }
});

}

You're in trouble here with your mindset.

You're asking for: If the input is invalid, wipe out the input.

This is problematic; it is impossible, short of pasting, to ever get to valid input without 'going through' invalid input.

Let's say I want to enter AA00, which is valid.

I click in your textbox, type 'A', and my A is immediately wiped out. After all, 'A' is invalid.

Even if you try to account for this by allowing a single character, or adjusting the rule of 'what is valid' with: "A single letter or digit is also valid", what you've created now is incredibly annoying. If I paste an ID from elsewhere and my ID starts with a space, then I think my computer is broken: I paste " AA00", and my text just disappears on me.

That's not how you build a good user interface.

Here's an alternate, just as simple approach:

You add a changed listener. You inspect the input. If the input is valid, colour the background of the input element in a light green tinge. If the input is empty, colour it the default background colour. Otherwise, give it a red tinge.

Now I get visual feedback as I type IDs.

The rule of thumb is rather simply: Do not mess with a user's input unless you really, REALLY know what you're doing .

You've created a really complicated regex. This trivial one will cover exactly what you asked for: 2 characters which can be letters or digits, followed by any number of digits:

Pattern.compile("^[a-zA-Z0-9]{2}[0-9]*$")

is all you need. It even reads like what you asked: '2 letters/digits', then 'any number of digits'.

assumed min size of 4 for below - can be changed as you need

public static final String C2_PRE_STR = "([a-zA-Z]{2}|\\d{2})\\d{2,}";

public static void main(String[] args) {
    List<String> valids = List.of("AA00", "AB123", "AA2345", "1234", "12345");
    List<String> invalids = List.of("1DAA", "D1D2", "DDDD", "A1", "11");

    System.out.printf("%10s %10s %10s %10s\n", "input", "expected", "actual", "matching?");
    valids.forEach(s -> System.out.printf("%10s %10s %10s %b\n", s, s, validatedValue(s), s.matches(C2_PRE_STR)));
    invalids.forEach(s -> System.out.printf("%10s %10s %10s %b\n", s, "", validatedValue(s), s.matches(C2_PRE_STR)));
}

private static String validatedValue(String input) {
    return input.matches(C2_PRE_STR) ? input : "";
}

produces below

> Task :RegEx.main()
     input   expected     actual  matching?
      AA00       AA00       AA00 true
     AB123      AB123      AB123 true
    AA2345     AA2345     AA2345 true
      1234       1234       1234 true
     12345      12345      12345 true
      1DAA                       false
      D1D2                       false
      DDDD                       false
        A1                       false
        11                       false

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM