I have a TextField in javaFX where the background color changes accordingly to if the content is valid or not.
Valid:
987654321 1
987654321 21
0101 9 1
1701 91 1 2
4101 917 1 0 43
0801 9 178 2 0
0111 9 1 084 0
Invalid:
0101 9 1 0 1 0
3124
0314 9
Basically:
- Only digits
- First group 4 or 9 digits
- If first group 9 digits -> only two groups in total
- If first group 4 digits -> three, four or five groups in total
- Group two and three digits 1-9999
- Group four and five digits 0-9999
Now think one of these (valid) lines as one "Ident".
The current regex is:
final String base = "(\\d+\\s+\\d+)|(\\d+\\s+\\d+\\s+\\d+(\\s+\\d+)?(\\s+\\d+)?)|(\\d+\\s+\\d+\\s+\\d+)|(\\d+\\s+\\d+\\s+\\d+\\s+\\d+)|(\\d+\\s+\\d+\\s+\\d+\\s+\\d+\\s+\\d+)";
Which works great so far, but now I want to include csv. So I can type only one ident as I have used to, or multiple idents separated by comma (,), but not more than five idents in total.
My attempt:
final String pattern = String.format("(%s,?\\s*){1,5}",base);
This enables me to input this:
- All the valid lines above
- 0101 9 1, 0101 9 2, 0101 9 3
- 0101 9 1, 987654321 21, 0101 9 3, 0101 9 4
And if I input more than 5 idents it turns invalid correctly. But if I input the invalid ident 0101 9 1 1 1 1 1 1 1 1 1 it still turns valid.
Any suggestions?
EDIT: This is the matching logic:
private final Predicate<String> typingPredicate = new Predicate<String>() {
@Override
public boolean apply(String input) {
return input.matches(pattern);
}
};
textField.textProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> observableValue, String previous, String current) {
if (current != null) {
if (StringUtils.isEmpty(current) || typingPredicate.apply(current.trim())) {
textField.getStyleClass().removeAll("invalid");
} else {
textField.getStyleClass().add("invalid");
}
}
}
});