【问题标题】:Java String.matches regex with OR pipe [duplicate]Java String.matches正则表达式与OR管道[重复]
【发布时间】:2011-06-13 20:59:48
【问题描述】:

我正在尝试进行以下匹配,但它没有像我预期的那样返回 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].

帮助赞赏,
公里


通过做得到它的工作

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

【问题讨论】:

    标签: java regex


    【解决方案1】:

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

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

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

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

    但即使这样也不对:

    1. 您真正需要做的(我认为)是匹配提供的属性,而与用户提供它们的顺序无关。
    2. 如果用户输入诸如“meaningfullname”之类的内容,上述简单的正则表达式将不匹配。

    真的,使用正则表达式太复杂了。相反,你最好用这样的东西:

    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!");
        }
    }
    

    【讨论】:

    • 谢谢!我实际上不想匹配文字'|'特点。我只是将它用作分隔属性的语法手段。
    • @ktm5124 - 我想通了。请参阅我的更新答案。
    【解决方案2】:

    java String::matches() 只匹配整个字符串。你需要类似的东西

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

    或者使用 Pattern 类

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

    【讨论】:

    • 对!我忘记写了。*我已经很久没有做正则表达式了。我通过使更改反映在我原来的问题中来使它起作用。
    • 为什么你认为另一种方式更好?它涉及更多代码! (更少的计算?)
    • 我建议您尝试运行建议的代码并检查其结果。它没有做你认为它正在做的事情。
    • 我有一组有限的属性(实际上列出的四个是完整的)。我相信它不起作用的唯一情况是存在与属性不匹配的前导字符序列。但在这种情况下,程序将无法正确配置,我不希望它运行。另外:代码通过了我所有的测试。
    • 实际上,split("\|") 甚至不会编译。要在 regex \| 上拆分,您必须编写 split("\\|")
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2013-03-21
      • 1970-01-01
      • 2017-03-01
      • 2020-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-03
      • 2012-02-13
      相关资源
      最近更新 更多