有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

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

例如:

答:是的

@a:没错

a@$:假

a@n01:对

an01:错

a:错

@:错

我试过了

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

我希望这能匹配任何一个特殊角色的出现。但是,不,我只需要一个场景中的任何一个

我也试过交替,但解决不了


共 (2) 个答案

  1. # 1 楼答案

    我希望这个答案对你们有用,如果不是的话,可能对未来的读者有用。在这里,我首先要做两个假设:1)你不需要正则表达式本身,你是用Java编程的。2) 您可以访问Java8

    这可以通过以下方式实现:

    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. String中获取IntStream(由字符组成)
    3. 过滤每一个char,仅当它们在List<Character>中时才保留在流中
    4. 仅当List<Character>中的count() == 1字符正好存在时才返回true

    该代码可用作:

    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

  2. # 2 楼答案

    维韦克,你的正则表达式真的很接近。这是你要找的一行正则表达式

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

    demo

    它是如何工作的

    1. ^$锚确保我们匹配的是整个字符串,避免以后与禁止字符进行部分匹配
    2. 向前看确保我们至少有一个数字或字母
    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]*");
    

    我的正则表达式怎么了

    事实上,你的正则表达式就快到了。这就是我们所缺少的

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

    交替选择

    由于您尝试了替代,请记住,这里有一种方法:

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

    demo

    如果你有任何问题,请告诉我