Java REGEX с фильтром документов - PullRequest
0 голосов
/ 18 декабря 2018

Я пытался выяснить выражения REGEX, которые могут фильтровать символы, которые не являются '-' или 0-9.Это выражение будет использоваться с фильтром документа, который будет фильтровать символы, вставляемые в JTextFields.Позвольте мне объяснить более подробно ...

Когда пользователь вводит символ в JTextField, DocumentFilter проверяет ввод, используя метод replace в классе DocumentFilter.Поскольку метод вызывается каждый раз, когда вставляется символ, REGEX должен был иметь возможность обрабатывать части целого числа, когда пользователь строит строку.Например,

Key Press 1): Value = '-' PASS
Key Press 2): Value = '-1' PASS
Key Press 3): Value = '-10' PASS etc...

Однако фильтр не должен разрешать комбинацию '-0' или '-' и должен пропускать следующие случаи:

Только отрицательный символ ('-')

Отрицательный номер без нуля рядом с '-' (сбой '-01')

Положительные значения (проход 0122 и 122)

Вот мой код:

package regex;

import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;

public class CustomFilter extends DocumentFilter {

    private String regex = "((-?)([1-9]??))(\d)";

    /**
     * Called every time a new character is added.
     */
    @Override
    public void insertString(DocumentFilter.FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException {

        String text = fb.getDocument().getText(0, fb.getDocument().getLength());
        text += string;

        if(text.matches(regex)) {
            super.insertString(fb, offset, string, attr);
        }
    }

    /**
     * Called when the user pastes in new text.
     */
    @Override
    public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {

        String string = fb.getDocument().getText(0, fb.getDocument().getLength());
        string += text;

        if(string.matches(regex)) {
            super.replace(fb, offset, length, text, attrs);
        }
    }

    @Override
    public void remove(FilterBypass fb, int offset, int length) throws BadLocationException {
        super.remove(fb, offset, length); // I may modify this later
    }
}

Если вы считаете, что я иду по неверному пути, пожалуйста, дайте мне знать.Я открыт для более упрощенного варианта.

Ответы [ 2 ]

0 голосов
/ 18 декабря 2018

Вместо всех чередований уменьшите его до этого

"^(?=[-\\d])(?:-(?!0))?\\d*$"

Объяснено

 ^                             # Beginning of string
 (?= [-\d] )                   # Must be a character in it
 (?:                           # Optional minus sign
      -
      (?! 0 )                       # If not followed by 0
 )?
 \d*                           # Optional digits [0-9]
 $                             # End of string

Мод:

Приложив немного дополнительных усилий, вы могли бы получить частично действительную строку в
группе захвата 1 и любых оставшихся недопустимых конечных символов в группе 2.

Все, что для этого требуется, - это проверить, есть ли совпадение.
Конечно, вам нужен сопоставитель, чтобы получить группы.

Возможные результаты:

  1. Регулярное выражение несоответствует, строка пуста.
    Действие: не предпринимать никаких действий.
  2. Соответствует регулярному выражению.
    a .Действие: Если длина группы 2> 0, запишите в текстовое поле
    строку группы 1 и поместите курсор в конец.
    b .Действие: Если длина группы 2 == 0, не предпринимать никаких действий, ввод идет правильно.

"^(?=.)((?:-(?>(?=0)|\\d*)|\\d*))(.*)$"

https://regex101.com/r/oxmZfa/1

Объяснено

 ^                             # Beginning of string

 (?= . )                       # Must be a character in the string

 (                             # (1 start), Template for pattial validity
      (?:
           -                             # The case for minus
           (?>                           # Atomic group for safety
                (?= 0 )                       # Don't capture 0 if it's ahead
             |                              # or,
                \d*                           # Any digits, 0 won't be first
           )
        |                              # or, the case for No minus
           \d*                           # Any digits
      )
 )                             # (1 end)

 ( .* )                        # (2), This is to be trimmed, stuff here doesn't match the template

 $                             # End of string

Когда пользователь отправляет текст, используйте это регулярное выражение для проверки ввода.
Если он не совпадает, пользователь не добавляет цифры в поле.
Просто выведите сообщение, чтоввод неполный.

"^(?=[-\\d])(?:-(?!0))?\\d+$"

0 голосов
/ 18 декабря 2018

Я наконец понял это сразу после публикации этого вопроса!(забавно, как все получается)

Выражение регулярного выражения: ^(-{1})|(-[1-9])|(-[1-9]([0-9]{1,}))|([0-9]{1,})$

Для тех, кто не знал (как я) '|'является символом ИЛИ в регулярном выражении.Таким образом, это выражение позволит значениям проходить путем совпадения строки в шагах,

(-{1}) Пропускает один '-'

(-[1-9]) Пропускает '-', к которому добавляется одно ненулевое целое число

(-[1-9]([0-9]{1,})) Пропускает '-' с одним ненулевым целым числом, добавленным к нему, а также разрешает любое количество целых чисел после этого прохода

([0-9]{1,}) Пропускает любое положительное целое число независимо от начального целого числа

Надеюсь, это поможет!

...