Java String.matches regex 与 OR 管道
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4771447/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java String.matches regex with OR pipe
提问by ktm5124
I am trying to make the following match, but it is not returning true as I would expect:
我正在尝试进行以下匹配,但它没有像我期望的那样返回 true:
String attrs = "id|fullname|email|title";
String regex = "fullname|email";
return attrs.matches(regex);
Instead it returns false.
相反,它返回 false。
Why is this? I expect the | pipe in attrs to be interpreted literally as an ASCII character, and the | pipe in regex to be interpreted according to regular expressions (i.e. OR).
为什么是这样?我期待 | attrs 中的管道从字面上解释为 ASCII 字符,而 | 正则表达式中的管道将根据正则表达式(即 OR)进行解释。
The reason I ask is because I am writing an application where I let the user set the attributes in the format attr1|attr2|attr3|..., and I want to verify his/her input by matching it against the possible attribute values: attr1|attr2|attr3|...|attr[n].
我问的原因是因为我正在编写一个应用程序,我让用户以 attr1|attr2|attr3|... 格式设置属性,我想通过将其与可能的属性值进行匹配来验证他/她的输入: attr1|attr2|attr3|...|attr[n]。
Help appreciated,
ktm
感谢帮助,
ktm
Got it working by doing
通过做得到它
String regex = "id.*|fullname.*|email.*|title.*";
String attrs = "fullname|email";
return attrs.matches(regex);
回答by Stephen C
The problem is that the pipe character is a meta-character in regexes. It therefore needs to be escaped if you want to match a literal '|'
character.
问题是管道字符是正则表达式中的元字符。因此,如果您想匹配文字'|'
字符,则需要对其进行转义。
String attrs = "id|fullname|email|title";
String regex = "fullname\|email";
return attrs.matches(regex);
The other problem is that your usecase really needs to be using find
rather than matches
, and the String
API does not support find
. This means you need to rewrite it to use an explicit Pattern
and Matcher
; e.g.
另一个问题是您的用例确实需要使用find
而不是matches
,并且String
API 不支持find
. 这意味着您需要重写它以使用显式Pattern
和Matcher
;例如
String attrs = "id|fullname|email|title";
Pattern regex = Pattern.compile("fullname\|email");
return regex.matcher(attrs).find();
But even this is not right:
但即使这样也是不对的:
- What you really need to do (I think) is match the supplied attributes independent of the order in which the user provides them.
- Naive regexes above will mismatch if the user enters something like "meaningfullname".
- 您真正需要做的(我认为)是匹配提供的属性,而与用户提供它们的顺序无关。
- 如果用户输入诸如“meaningfullname”之类的内容,上面的朴素正则表达式将不匹配。
Really, this is getting too complicated to do using regexes. Instead, you are better off with something like this:
真的,这变得太复杂了,无法使用正则表达式。相反,您最好使用以下方法:
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");
}
}
or if you just want to test if the attributes contain one or more of fullname
and email
或者如果您只想测试属性是否包含一个或多个fullname
和 email
String[] suppliedAttrs = supplied.split("\|");
for (String s: suppliedAttrs) {
if (s.equals("fullname") || s.equals("email")) {
System.err.println("BINGO!");
}
}
回答by KitsuneYMG
java String::matches() matches only whole strings. You need something like
java String::matches() 只匹配整个字符串。你需要类似的东西
try: regex =".*(fullname|email).*
;
尝试:regex =".*(fullname|email).*
;
Or use the Pattern class
或者使用 Pattern 类
A better way of doing what you want is String[] rattrs = attrs.split("\\|")
and then check each string.
做你想做的更好的方法是String[] rattrs = attrs.split("\\|")
然后检查每个字符串。
回答by maaartinus
You're using matches
, not find
, so it must correspond with the whole string.
您使用的是matches
, 不是find
,因此它必须与整个字符串相对应。