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?]*[*]?$