Java String.matches正则表达式与OR管道

时间:2011-01-22 23:59:52

标签: java regex

我正在尝试进行以下匹配,但它没有像我期望的那样返回true:

String attrs = "id|fullname|email|title";
String regex = "fullname|email";
return attrs.matches(regex);

相反,它返回false。

这是为什么?我期待| attrs中的管道按字面解释为ASCII字符,以及|正则表达式中的管道根据正则表达式(即OR)进行解释。

我问的原因是因为我正在编写一个应用程序,我让用户以attr1 | attr2 | attr3 | ...格式设置属性,我想通过匹配可能来验证他/她的输入属性值:attr1 | attr2 | attr3 | ... | attr [n]。

帮助表示赞赏,
KTM


通过

完成工作
String regex = "id.*|fullname.*|email.*|title.*";
String attrs = "fullname|email";
return attrs.matches(regex);

3 个答案:

答案 0 :(得分:7)

问题是管道符是正则表达式中的元字符。因此,如果要匹配文字'|'字符,则需要进行转义。

String attrs = "id|fullname|email|title";
String regex = "fullname\\|email";
return attrs.matches(regex);

另一个问题是您的用例确实需要使用find而不是matches,并且String API不支持find。这意味着您需要重写它以使用明确的PatternMatcher; e.g。

String attrs = "id|fullname|email|title";
Pattern regex = Pattern.compile("fullname\\|email");
return regex.matcher(attrs).find();

但即使这样也不对:

  1. 您真正需要做的(我认为)与提供的属性相匹配,与用户提供它们的顺序无关。
  2. 如果用户输入“有意义的名字”之类的内容,上面的朴素正则表达将不匹配。
  3. 真的,使用正则表达式变得太复杂了。相反,你最好用这样的东西:

    List<String> attrs = Arrays.asList(
            new String[] {"id", "fullname", "email", "title"});
    String[] suppliedAttrs = supplied.split("\\|");
    for (String s: suppliedAttrs) {
        if (!attrs.contains(s)) {
            throw new IllegalArgumentException("'" + s + "' is not valid");
        }
    }
    

    或者您只想测试属性是否包含fullnameemail

    中的一个或多个属性
    String[] suppliedAttrs = supplied.split("\\|");
    for (String s: suppliedAttrs) {
        if (s.equals("fullname") || s.equals("email")) {
            System.err.println("BINGO!");
        }
    }
    

答案 1 :(得分:5)

java String :: matches()仅匹配整个字符串。你需要像

这样的东西

尝试:regex =".*(fullname|email).*;

或使用Pattern类

更好的做法是String[] rattrs = attrs.split("\\|"),然后检查每个字符串。

答案 2 :(得分:2)

您使用的是matches,而不是find,因此它必须与整个字符串相对应。