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

时间:2014-05-29 09:27:00

标签: java regex

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

例如:

a @:true

@a:true

@ $:false

a @ n01:true

an01:false

a:false

@:false

我试过

 [0-9A-Za-z]*[@#%$]{1}[0-9A-Za-z]*

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

我也尝试过轮换,但无法解决。

2 个答案:

答案 0 :(得分:13)

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

^(?=.*?[0-9a-zA-Z])[0-9a-zA-Z]*[@#$%][0-9a-zA-Z]*$

请参阅demo

它是如何运作的?

  1. ^$锚点确保我们匹配的是整个字符串,以避免以后与禁用字符部分匹配。
  2. (?=.*?[0-9a-zA-Z])前瞻确保我们至少有一个数字或字母。
  3. [0-9a-zA-Z]*[@#$%][0-9a-zA-Z]*匹配零个或多个字母或数字,后跟完全一个字符@#$%,后跟零个或多个字母或数字 - 确保我们有一个特殊字符但不能再有。
  4. <强>实施

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

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

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

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

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

      由于你尝试过替换,为了记录,这是一种方法:

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

      请参阅demo

      如果您有任何问题,请与我们联系。

答案 1 :(得分:1)

我希望这个答案对你有用,如果没有,它可能是为了未来的读者。我将在前面做两个假设:1)你不需要正则表达式,你用Java编程。 2)您可以访问Java 8。

这可以通过以下方式完成:

private boolean stringMatchesChars(final String str, final List<Character> characters) {
    return (str.chars()
            .filter(ch -> characters.contains((char)ch))
            .count() == 1);
}

我在这里:

  1. 使用StringList<Character>个允许的内容作为输入。
  2. IntStream获取String(由字符组成)。
  3. 过滤每个char,只有在List<Character>中才会保留在流中。
  4. 仅当truecount() == 1中的字符,只有一个存在时)才会返回List<Character>
  5. 代码可以用作:

    String str1 = "a";
    String str2 = "a@";
    String str3 = "a@@a";
    String str4 = "a#@a";
    List<Character> characters = Arrays.asList('@', '#', '$', '%');
    
    System.out.println("stringMatchesChars(str1, characters) = " + stringMatchesChars(str1, characters));
    System.out.println("stringMatchesChars(str2, characters) = " + stringMatchesChars(str2, characters));
    System.out.println("stringMatchesChars(str3, characters) = " + stringMatchesChars(str3, characters));
    System.out.println("stringMatchesChars(str4, characters) = " + stringMatchesChars(str4, characters));
    

    导致falsetruefalsefalse