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.