Java 具有 "Joker" 个字符的正则表达式

Java Regex with "Joker" characters

我尝试使用正则表达式验证输入字段。 我所说的 "joker" 个字符是 '?'和 '*'。 这是我的 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-zA-Z\d]\?*){2,}\*?$

解释:

正则表达式断言此模式必须出现两次或更多次:

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

断言 class [a-zA-Z\d] 中必须有一个字符,其左侧或右侧有 0 到无穷大的问号。

然后,正则表达式匹配字符串末尾的 \*?,这意味着 0 或 1 个星号字符。

Demo

这是一个更快的替代正则表达式,正如评论中建议的那样:

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

Demo

给你:

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

两者均在 Regex101 中进行了说明。

  • ^ 是字符串的开始
  • \?* 表示任意数量的初始 ? 字符(必须转义)
  • \w{2,} 至少 2 个字母数字字符
  • \?* 继续任意数量和 ? 个字符
  • \*? 和最后一个 * 字符
  • (?<!\s) 并且整个字符串必须没有 \s 白色字符(使用否定后视)
  • $ 是字符串的结尾

解决此问题的其他方法可能是 look-ahead mechanism (?=subregex). It is zero-length(它将正则表达式光标重置为执行 subregex 之前的位置),因此它允许正则表达式引擎通过构造对同一文本进行多次测试

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

注意: 最后一个条件 (conditionN) 没有放在 (?=...) 中,让正则表达式引擎在测试部分后移动光标 (到 "consume" 它)并在它之后继续测试其他东西。但是为了使 conditionN 必须匹配 精确地 我们想要 "consume" 的部分(早期的条件没有这个限制,它们可以匹配任何子字符串长度,比如让我们说几个第一个字符)。

所以现在我们需要考虑一下我们的条件是什么。

  • 我们只想匹配 alphanumeric characters?*,但 * 只能(可选)出现在末尾。我们可以写成^[a-zA-Z0-9?]*[*]?$。这也处理非空白字符,因为我们没有将它们作为可能接受的字符包括在内。

  • 第二个要求是"Minimum 2 alpha-numeric characters"。它可以写成 .*?[a-zA-Z0-9].*?[a-zA-Z0-9](?:.*?[a-zA-Z0-9]){2,}(如果我们喜欢更短的正则表达式)。由于该条件实际上并未测试 整个 文本,而是仅测试其中的一部分,因此我们可以将其置于先行机制中。

以上条件似乎涵盖了我们想要的所有内容,因此我们可以将它们组合成正则表达式,如下所示:

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