2011-01-22 61 views
2

我试图让下面的比赛,但不返回true,因为我所期望的:的Java String.matches正则表达式或管道

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); 

回答

5

Java字符串::匹配()只匹配整个字符串。你需要像

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

或者使用模式类

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

2

您使用matches,不find工作,所以它必须与整个字符串对应。

6

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

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. 如果用户输入“意义全名”之类的内容,上面的朴素正则表达式将会不匹配。

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

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

谢谢!我其实不想匹配字面上的'|'字符。我只是用它作为分离属性的语法手段。 – ktm5124 2011-01-23 00:18:21

+0

@ ktm5124 - 我明白了。看到我更新的答案。 – 2011-01-23 00:22:04