带有“Joker”字符的Java Regex

我尝试使用正则表达式validation输入字段。 我称之为“小丑”的角色是’?’ 和’*’。 这是我的java正则表达式:

"^$|[^\\*\\s]{2,}|[^\\*\\s]{2,}[\\*\\?]|[^\\*\\s]{2,}[\\?]{1,}[^\\s\\*]*[\\*]{0,1}" 

我想要匹配的是:

  • 至少2个字母数字字符(除了’?’和’*’)
  • ‘*’只能出现一次并出现在字符串的末尾
  • ‘?’ 可以出现多次
  • 根本没有WhiteSpace

例如:

  • abcd =好的
  • ?bcd =好的
  • AB? =好的
  • ab * =好的
  • ab?* =好的
  • ?? cd = OK
  • * ab =不行
  • ??? =不行
  • ab cd =不行
  • abcd =不行(开头的空间)

我让正则表达式有点复杂,我迷失了你能帮助我吗?

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

说明:

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

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

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

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

演示

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

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

演示

干得好:

 ^\?*\w{2,}\?*\*?(? 

两者都在Regex101上进行了描述。

  • ^是String的开头
  • \?*表示任意数量的初始? 字符(必须转义)
  • \w{2,}至少2个字母数字字符
  • \?*继续任意数量和? 人物
  • \*? 以及可选的最后一个*字符
  • (?并且整个String必须没有白色字符(使用负面后卫)
  • $是String的结尾

解决此问题的其他方法可能是使用(?=subregex)机制(?=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?]*[*]?$