我在javaFX中有一个TextField,其中的背景颜色会根据内容的有效与否而相应地更改。
有效的:

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
无效的:
0101 9 1 0 1 0
3124
0314 9
基本上:
  • 只有数字
  • 第一组4或9位数字
  • 如果第一组9位数->总共
  • 仅两组
  • 如果第一组4位数字->总共
  • 三,四或五组
  • 组两位和三位数字1-9999
  • 组四位数和五位数0-9999

  • 现在,将这些(有效)行之一视为一个“Ident”。
    当前的正则表达式为:
    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+)";
    
    到目前为止效果很好,但是现在我要包含csv。因此,我只能输入以前使用的一个标识,也可以输入多个以逗号(,)分隔的标识,但总共不能超过五个。
    我的尝试:
    final String pattern = String.format("(%s,?\\s*){1,5}",base);
    
    这使我可以输入以下内容:
  • 上方的所有有效行
  • 0101 9 1,0101 9 2,0101 9 3
  • 0101 9 1,987654321 21,0101 9 3,0101 9 4

  • 而且,如果我输入了5个以上的标识,它将正确地变为无效。
    但是,如果我输入了无效的标识0101 9 1 1 1 1 1 1 1 1 1 1,它将仍然有效。
    有什么建议么?
    编辑:这是匹配的逻辑:
    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");
                }
            }
        }
    });
    

    最佳答案

    您的正则表达式中的逗号是可选,它实际上允许将“0101 9 1 1 1 1 1 1 1 1 1 1 1”自由地解析为两个或更多记录。

    要解决此问题,您可能要求它要么是一个标识,要么是多个逗号分隔的标识:

    final String pattern = String.format("(%s\\s*,\\s*){0,4}%s",base,base);
    

    我也建议对输入规则进行严格的设置,尽管它似乎与问题没有直接关系。

    09-29 21:49