【问题标题】:Java Regex with "Joker" characters带有“Joker”字符的 Java 正则表达式
【发布时间】:2019-01-17 21:21:14
【问题描述】:

我尝试使用正则表达式验证输入字段。 我所说的“小丑”字符是“?”和 '*'。 这是我的 java 正则表达式:

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

我要匹配的是:

  • 至少 2 个字母数字字符(“?”和“*”除外)
  • “*”只能出现一次,并且位于字符串的末尾
  • “?”可以出现多次
  • 根本没有空格

例如:

  • abcd = 好的
  • ?bcd = 正常
  • ab?? = 好的
  • ab*= 正常
  • ab?* = 正常
  • ??cd = 正常
  • *ab = 不正常
  • ??? = 不行
  • ab cd = 不正常
  • abcd = 不正确(开头有空格)

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

【问题讨论】:

  • 你可以使用网站来测试你的正则表达式,看看有什么问题,比如regexr.com
  • “a?b”呢?
  • a?b = 也可以
  • 试试^(?:\?*[a-zA-Z\d]){2}[^\s*]*\*?$。在此处查看现场演示regex101.com/r/XgqAej/1
  • 旁注:那些“小丑”字符实际上被称为wildcards

标签: java regex metacharacters


【解决方案1】:
^(?:\?*[a-zA-Z\d]\?*){2,}\*?$

解释:

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

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

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

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

Demo

这是一个更快的替代正则表达式,如 cmets 中建议的 revo:

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

Demo

【讨论】:

  • 这是正确的答案,但我认为在找到第二个字母数字字符后无需遍历整个组。我上面评论的一些修改版本:^(?:\?*[a-zA-Z\d]){2}[a-zA-Z\d?]*\*?$
  • 我在我的问题中用空格犯了一个错误,我希望允许空格,但不允许在“通配符”字符之前或之后使用空格。像这样:ab cd =ok |一种? cd =不好| ab ?cd =not ok (与 '*' 相同)
  • 您的编辑使这里的大多数答案无效。不鼓励这种行为。我已经回滚了编辑。您可以发布一个新问题。 @MattZdj
  • 好的,我发布一个新问题
【解决方案2】:

给你:

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

两者都在Regex101 演示。

  • ^ 是字符串的开头
  • \?* 表示任意数量的初始 ? 字符(必须转义)
  • \w{2,} 至少 2 个字母数字字符
  • \?* 以任意数量和 ? 字符继续
  • \*? 和可选的最后一个 * 字符
  • (?&lt;!\s) 和整个字符串不能有 \s 白色字符(使用负后视)
  • $ 是字符串的结尾

【讨论】:

  • Op 澄清这两个字符不必相邻:a?b 也可以。而且只能有0..1个“*”,而且只能在末尾。
  • 消极的后视是多余的。它也不匹配a?b
【解决方案3】:

解决此问题的其他方法可能是使用look-ahead 机制(?=subregex)。它是zero-length(它将正则表达式光标重置为执行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?]*[*]?$

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-28
    • 1970-01-01
    • 2012-11-20
    • 2013-01-29
    • 2011-02-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多