0

I have this piece of code which is supposed to remove any non-character value and replace it with a blank space (it deletes the non-character value)

public void firstNameOnlyText() {
    txtFirstName.textProperty().addListener(new ChangeListener<String>() {
        public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {

            if (!newValue.matches("\\D*")) {
                    txtFirstName.setText(newValue.replaceAll("[^\\D]", ""));
                }
            }
    });
}

The code works perfectly to remove numbers, but I don't know what regex to use so it also replaces punctuations (e.g `, !, ], [ etc.)

Can someone help me?

Michael
  • 41,989
  • 11
  • 82
  • 128

2 Answers2

3

First, don't use a listener for this functionality. The problem here is that if you have another listener on the text field's text property, that listener will see both the invalid state (with the non-character input), before it reverts to the valid state. The purpose of any kind of filter on a text field should be to ensure that only valid state is seen. You should use a TextFormatter instead.

Regex rules are described in the Pattern documentation. If you want to allow any upper or lower case alphabetic character you can use "[a-zA-Z]"; if you want to explicitly match the rules for Character.isLowerCase() or Character.isUpperCase(), you can use

"[\\p{javaLowerCase}\\p{javaUpperCase}]".

Here's an example:

Pattern pattern = Pattern.compile("[a-zA-Z]*");
UnaryOperator<TextFormatter.Change> filter = c -> {
    if (pattern.matcher(c.getControlNewText()).matches()) {
        return c ;
    } else {
        return null ;
    }
};
TextFormatter<String> formatter = new TextFormatter<>(filter);
txtFirstName.setTextFormatter(formatter);
James_D
  • 201,275
  • 16
  • 291
  • 322
  • Thank you for your work and the link to the pattern documentation (it helped, I was looking at older versions of it). I fixed my method by adding "[a-zA-Z]" and "[\\d||\\p{Punct}]" respectively (thank you for suggesting it) –  Apr 18 '18 at 14:54
0

You can use an negated regular expression set ^ to keep only A to Z (case insensitive). If the filtered string is different, set the value of the text box.

final String filtered = newValue.replaceAll("[^a-zA-Z]", "");
if (!newValue.equals(filtered)) {
    // set 
}
Michael
  • 41,989
  • 11
  • 82
  • 128
  • I actually did newValue.replaceAll("[\\d || \\p{Punct}]", ""); (this replaces all the number & the punctuation with empty spaces) –  Apr 18 '18 at 15:02