仅匹配给定集合中一个字符的匹配项

Viv*_*han 9 java regex

我需要验证一个输入字符串,这样true只有当字符串包含一个特殊字符@#$%,只有一个,最多一次时,验证才会返回.字母和数字可以是任何地方,可以重复任意次数,但至少应该有一个数字或字母

例如:

一个@:真的

@a:是的

一个@ $:false

a @ n01:是的

an01:错误

a:假

@:false

我试过了

 [0-9A-Za-z]*[@#%$]{1}[0-9A-Za-z]*
Run Code Online (Sandbox Code Playgroud)

我希望这会匹配任何特殊字符的一次出现.但不是.我只需要在集合中出现任何一个.

我也试过交替,但无法解决它.

zx8*_*x81 13

Vivek,你的正则表达式非常接近.这是您正在寻找的单行正则表达式.

^(?=.*?[0-9a-zA-Z])[0-9a-zA-Z]*[@#$%][0-9a-zA-Z]*$
Run Code Online (Sandbox Code Playgroud)

演示

它是如何工作的?

  1. ^$锚确保无论我们是匹配整个字符串,避免与禁止文字部分匹配后.
  2. (?=.*?[0-9a-zA-Z])预测先行确保我们至少有一个数字或字母.
  3. [0-9a-zA-Z]*[@#$%][0-9a-zA-Z]*场比赛零个或多个字母或数字,后紧跟一个字符可以是一个@,#,$或者%,后跟零个或多个字母或数字,这可以确保我们有一个特殊字符,但没有更多.

履行

我相信你知道如何在Java中实现它,但是为了测试字符串是否匹配,你可以使用这样的东西:

boolean foundMatch = subjectString.matches("^(?=[0-9a-zA-Z]*[@#$%][0-9a-zA-Z]*$)[@#$%0-9a-zA-Z]*");
Run Code Online (Sandbox Code Playgroud)

我的正则表达式出了什么问题?

实际上,你的正则表达式几乎就在那里.这是缺少的.

  1. 因为你没有^$锚,所以正则表达式能够匹配字符串的子集,例如a#in a##%%,这意味着特殊字符可以出现在字符串中,但在匹配之外.不是你想要的:我们需要通过锚定它来验证整个字符串.
  2. 你需要一些东西来确保至少有一个字母或数字.你肯定可以通过交替完成它,但在这种情况下,前瞻更紧凑.

替代与交替

由于您尝试了更改,为了记录,这是一种方法:

^(?:[0-9a-zA-Z]+[@#$%][0-9a-zA-Z]*|[0-9a-zA-Z]*[@#$%][0-9a-zA-Z]+)$
Run Code Online (Sandbox Code Playgroud)

演示.

如果您有任何疑问,请告诉我.

  • @VivekVardhan`(?=`表示`断言在这个位置我们可以匹配...`匹配什么?匹配`.*?[0-9a-zA-Z]`这意味着任意数量的字符`.*`后面跟着通过`[0-9a-zA-Z]`一个字母或数字.````中的`?`使得量词变得懒惰,影响回溯 - 在你的正则表达式中不重要,它可以使用或不使用它.我相信你的世界正则表达统治的下一站是[Mastering Lookahead and Lookbehind](http://www.rexegg.com/regex-lookarounds.html) (2认同)