问题
I try to have a regex validating an input field. What i call "joker" chars are '?' and '*'. Here is my java regex :
"^$|[^\\*\\s]{2,}|[^\\*\\s]{2,}[\\*\\?]|[^\\*\\s]{2,}[\\?]{1,}[^\\s\\*]*[\\*]{0,1}"
What I'm tying to match is :
- Minimum 2 alpha-numeric characters (other than '?' and '*')
- The '*' can only appears one time and at the end of the string
- The '?' can appears multiple time
- No WhiteSpace at all
So for example :
- 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)
I've made the regex a bit complicated and I'm lost can you help me?
回答1:
^(?:\?*[a-zA-Z\d]\?*){2,}\*?$
Explanation:
The regex asserts that this pattern must appear twice or more:
\?*[a-zA-Z\d]\?*
which asserts that there must be one character in the class [a-zA-Z\d]
with 0 to infinity questions marks on the left or right of it.
Then, the regex matches \*?
, which means an 0 or 1 asterisk character, at the end of the string.
Demo
Here is an alternative regex that is faster, as revo suggested in the comments:
^(?:\?*[a-zA-Z\d]){2}[a-zA-Z\d?]*\*?$
Demo
回答2:
Here you go:
^\?*\w{2,}\?*\*?(?<!\s)$
Both described at demonstrated at Regex101.
^
is a start of the String\?*
indicates any number of initial?
characters (must be escaped)\w{2,}
at least 2 alphanumeric characters\?*
continues with any number of and?
characters\*?
and optionally one last*
character(?<!\s)
and the whole String must have not\s
white character (using negative look-behind)$
is an end of the String
回答3:
Other way to solve this problem could be with look-ahead mechanism (?=subregex)
. It is zero-length (it resets regex cursor to position it was before executing subregex
) so it lets regex engine do multiple tests on same text via construct
(?=condition1)
(?=condition2)
(?=...)
conditionN
Note: last condition (conditionN
) is not placed in (?=...)
to let regex engine move cursor after tested part (to "consume" it) and move on to testing other things after it. But to make it possible conditionN
must match precisely that section which we want to "consume" (earlier conditions didn't have that limitation, they could match substrings of any length, like lets say few first characters).
So now we need to think about what are our conditions.
We want to match only
alphanumeric characters
,?
,*
but*
can appear (optionally) only at end. We can write it as^[a-zA-Z0-9?]*[*]?$
. This also handles non-whitespace characters because we didn't include them as potentially accepted characters.Second requirement is to have "Minimum 2 alpha-numeric characters". It can be written as
.*?[a-zA-Z0-9].*?[a-zA-Z0-9]
or(?:.*?[a-zA-Z0-9]){2,}
(if we like shorter regexes). Since that condition doesn't actually test whole text but only some part of it, we can place it in look-ahead mechanism.
Above conditions seem to cover all we wanted so we can combine them into regex which can look like:
^(?=(?:.*?[a-zA-Z0-9]){2,})[a-zA-Z0-9?]*[*]?$
来源:https://stackoverflow.com/questions/51783464/java-regex-with-joker-characters