Java Regex с символами "Джокер"

Я пытаюсь использовать регулярное выражение для проверки поля ввода. Что я называю "джокерскими" символами? и '*'. Вот мое регулярное выражение Java:

"^$|[^\\*\\s]{2,}|[^\\*\\s]{2,}[\\*\\?]|[^\\*\\s]{2,}[\\?]{1,}[^\\s\\*]*[\\*]{0,1}"

Я привязываю к соответствию:

  • Минимум 2 буквенно-цифровых символа (кроме '?' И '*')
  • '*' Может появляться только один раз и в конце строки.
  • '?' может появляется несколько раз
  • Никакого белого пространства

Так например:

  • abcd = OK
  • ?bcd = OK
  • ab?? = OK
  • ab*= OK
  • ab?* = OK
  • ??cd = OK
  • *ab = NOT OK
  • ??? = NOT OK
  • ab cd = NOT OK
  • abcd = Not OK (space at the begining)

Я сделал регулярное выражение немного сложным, и я потерялся, вы можете мне помочь?

Вы можете использовать веб-сайт, чтобы проверить свое регулярное выражение и посмотреть, что не так, например regexr.com

Hearner 10.08.2018 11:37

А как насчет "а? Б"?

Sweeper 10.08.2018 11:45

a? b = тоже хорошо

Matt Zdj 10.08.2018 11:46

Попробуйте ^(?:\?*[a-zA-Z\d]){2}[^\s*]*\*?$. Смотрите живую демонстрацию здесь regex101.com/r/XgqAej/1

revo 10.08.2018 11:49

Примечание: эти символы-шутники на самом деле называются подстановочные знаки

Lino 10.08.2018 11:54
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
5
827
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий
^(?:\?*[a-zA-Z\d]\?*){2,}\*?$

Объяснение:

Регулярное выражение утверждает, что этот шаблон должен появляться дважды или более:

\?*[a-zA-Z\d]\?*

который утверждает, что в классе [a-zA-Z\d] должен быть один символ с вопросительными знаками от 0 до бесконечности слева или справа от него.

Затем регулярное выражение соответствует \*?, что означает символ звездочки 0 или 1 в конце строки.

Демо

Вот альтернативное регулярное выражение, которое работает быстрее, как было предложено в комментариях:

^(?:\?*[a-zA-Z\d]){2}[a-zA-Z\d?]*\*?$

Демо

Это правильный ответ, но я бы сказал, что нет необходимости проходить через всю группу после того, как будет найден второй буквенно-цифровой символ. Немного измененная версия из моего комментария выше: ^(?:\?*[a-zA-Z\d]){2}[a-zA-Z\d?]*\*?$

revo 10.08.2018 12:03

Я допустил ошибку в своем вопросе с пробелом. Я хочу, чтобы пробелы были разрешены, но не разрешены, если они находятся до или после символа "подстановки". вот так: ab cd = ok | а? cd = не в порядке | ab? cd = не в порядке (то же самое с '*')

Matt Zdj 14.08.2018 10:23

Ваше редактирование делает недействительными большинство ответов здесь. Такое поведение не приветствуется. Я откатил правку. Вы можете опубликовать новый вопрос. @MattZdj

Sweeper 14.08.2018 11:08

Хорошо, я публикую новый вопрос

Matt Zdj 14.08.2018 11:11

Ну вот:

^\?*\w{2,}\?*\*?(?<!\s)$

Оба описанных на продемонстрированном на Regex101.

  • ^ - начало строки
  • \?* указывает любое количество начальных символов ? (необходимо экранировать)
  • \w{2,} минимум 2 буквенно-цифровых символа
  • \?* продолжается любым количеством символов и ?.
  • \*? и, возможно, последний символ *
  • (?<!\s) и вся строка не должны содержать белый символ \s (с использованием отрицательной ретроспективы)
  • $ - это конец строки

Оп пояснил, что два символа не обязательно должны быть рядом: a? B тоже подойдет. А может быть только 0..1 "*" и только в конце.

Malte Hartwig 10.08.2018 11:57

Отрицательный взгляд назад является избыточным. Также не соответствует a?b

revo 10.08.2018 12:06

Другой способ решить эту проблему - использовать механизм (?=subregex)смотреть вперед. Это нулевой длины (он сбрасывает курсор регулярного выражения в положение, в котором он был до выполнения subregex), поэтому он позволяет механизму регулярных выражений выполнять несколько тестов для одного и того же текста с помощью конструкции

(?=condition1)  
(?=condition2)
(?=...)
conditionN       

Примечание: последнее условие (conditionN) не помещается в (?=...), чтобы позволить движку регулярных выражений перемещать курсор после тестируемой части (чтобы «потреблять» ее) и переходить к тестированию других вещей после нее. Но для того, чтобы сделать это возможным, conditionN должен соответствовать именно так той секции, которую мы хотим «потреблять» (в более ранних условиях этого ограничения не было, они могли соответствовать подстрокам любой длины, например, допустим, несколько первых символов).

Итак, теперь нам нужно подумать о наших условиях.

  • Мы хотим сопоставить только alphanumeric characters, ?, *, но * может появиться (необязательно) только в конце. Мы можем записать его как ^[a-zA-Z0-9?]*[*]?$. Это также обрабатывает непробельные символы, потому что мы не включили их как потенциально допустимые символы.

  • Второе требование - иметь «минимум 2 буквенно-цифровых символа». Его можно записать как .*?[a-zA-Z0-9].*?[a-zA-Z0-9] или (?:.*?[a-zA-Z0-9]){2,} (если нам нравятся более короткие регулярные выражения). Поскольку это условие на самом деле не проверяет текст весь, а только его часть, мы можем поместить его в механизм упреждения.

Вышеуказанные условия, похоже, охватывают все, что мы хотели, поэтому мы можем объединить их в регулярное выражение, которое может выглядеть так:

^(?=(?:.*?[a-zA-Z0-9]){2,})[a-zA-Z0-9?]*[*]?$

Другие вопросы по теме