Я пытаюсь использовать регулярное выражение для проверки поля ввода. Что я называю "джокерскими" символами? и '*'. Вот мое регулярное выражение Java:
"^$|[^\\*\\s]{2,}|[^\\*\\s]{2,}[\\*\\?]|[^\\*\\s]{2,}[\\?]{1,}[^\\s\\*]*[\\*]{0,1}"
Я привязываю к соответствию:
- 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)
Я сделал регулярное выражение немного сложным, и я потерялся, вы можете мне помочь?
А как насчет "а? Б"?
a? b = тоже хорошо
Попробуйте ^(?:\?*[a-zA-Z\d]){2}[^\s*]*\*?$
. Смотрите живую демонстрацию здесь regex101.com/r/XgqAej/1
^(?:\?*[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?]*\*?$
Я допустил ошибку в своем вопросе с пробелом. Я хочу, чтобы пробелы были разрешены, но не разрешены, если они находятся до или после символа "подстановки". вот так: ab cd = ok | а? cd = не в порядке | ab? cd = не в порядке (то же самое с '*')
Ваше редактирование делает недействительными большинство ответов здесь. Такое поведение не приветствуется. Я откатил правку. Вы можете опубликовать новый вопрос. @MattZdj
Хорошо, я публикую новый вопрос
Ну вот:
^\?*\w{2,}\?*\*?(?<!\s)$
Оба описанных на продемонстрированном на Regex101.
^
- начало строки\?*
указывает любое количество начальных символов ?
(необходимо экранировать)\w{2,}
минимум 2 буквенно-цифровых символа\?*
продолжается любым количеством символов и ?
.\*?
и, возможно, последний символ *
(?<!\s)
и вся строка не должны содержать белый символ \s
(с использованием отрицательной ретроспективы)$
- это конец строкиОп пояснил, что два символа не обязательно должны быть рядом: a? B тоже подойдет. А может быть только 0..1 "*" и только в конце.
Отрицательный взгляд назад является избыточным. Также не соответствует a?b
Другой способ решить эту проблему - использовать механизм (?=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?]*[*]?$
Вы можете использовать веб-сайт, чтобы проверить свое регулярное выражение и посмотреть, что не так, например regexr.com