Java Regex with “Joker” characters

半城伤御伤魂 提交于 2019-12-08 13:09:28

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!