java - Java 正则表达式验证器
问题描述
我将从 REST 服务请求有效负载中获取 where 子句字符串(仅用 AND/OR 运算符分隔的条件)。我想使用正则表达式验证输入字符串。条件将包含键运算符值格式的每个个体。
我在某种程度上尝试了实现这一目标。我是正则表达式的新手。我写了一些代码来验证这一点。但它正在部分工作。有人可以建议正确的正则表达式,如果可能的话,请解释它是如何工作的。这很有帮助。
所以我的问题是:我的正则表达式是否正确?如果是,为什么 matches() 方法对第二个和第三个输入字符串返回 false。
为了使它在任何复杂字符串出现时变得健壮,这个正则表达式会处理吗?例如:“(userName eq \"bjensen\" and familyName co \"O'Malley\") OR (userName eq \"bjensen\" or familyName co \"O'Malley\")"
我正在粘贴我的代码片段。
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class DummyTester {
public DummyTester() {
super();
}
public static void main(String[] args) {
checkRegex("userName eq \"bjensen\""); // returning Matches True
checkRegex("(userName eq \"bjensen\" and familyName co \"O'Malley\")"); // returning matches False
checkRegex("(userName eq \"bjensen\" and familyName co \"O'Malley\" AND userName eq \"bjensen\" AND familyName co \"O'Malley\")"); // returning matches False
}
static String checkRegex(String tester) {
String regex ="(\\w[\\w\\d]* \\s*(?:co|eq|gt)\\s* \\\"\\w[\\w\\d\\-\\:\\']*\\\")* ?(?:and|or|AND|OR)?";
System.out.println("The input rgex sis : "+regex);
System.out.println("The input String sis : "+tester);
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(tester);
boolean b = m.matches();
System.out.println("matcher is : "+ b);
while (m.find()) {
System.out.println(m.group());
}
return null;
}
}
上述代码片段的输出如下。
输出:
输入 rgex sis : (\w[\w\d]* \s*(?:co|eq|gt)\s* \"\w[\w\d-:\'] \") ?(? :and|or|AND|OR)?
输入字符串 sis : userName eq "bjensen"
匹配器是:真
输入字符串 sis : (userName eq "bjensen" and familyName co "O'Malley")
匹配器是:假
用户名 eq "bjensen" 和
familyName co“奥马利”
输入字符串 sis : (userName eq "bjensen" and familyName co "O'Malley" AND userName eq "bjensen" AND familyName co "O'Malley")
匹配器是:假
用户名 eq "bjensen" 和
familyName co“O'Malley”和
用户名 eq “bjensen” AND
familyName co“奥马利”
谢谢,维杰
解决方案
该matches()
函数尝试将整个输入正则表达式与您的输入进行匹配。您的正则表达式正在寻找:
[name] [operator] [string] [optional and-or]
因此,当您输入多个条件时,例如:"(userName eq \"bjensen\" and familyName co \"O'Malley\")"
,正则表达式将不会匹配整个输入,而只会匹配第一个and
。但第一个测试字符串不是这种情况,即"userName eq \"bjensen\""
.
所以你的代码需要是:
boolean b = m.matches();
System.out.println("matcher is : "+ b);
if (b) { // we have a complete match
System.out.println(m.group());
}
else {
while (m.find()) {
System.out.println(m.group());
}
}
但是有一些事情可以用你的正则表达式来改进。首先,您定义它的方式,它将接受为有效输入:
用户名 eq "bjensen" 和
...它有一个“悬空”和
如果您假设输入始终正确并且您不需要验证输入,这可能不是问题。但我建议对不允许上述字符串的正则表达式进行更改。此外,字符类\w
实际上等价于[A-Za-z0-9_]
. 您正在尝试将名称匹配到:
\w[\w\d]*
但\w
已经包括了所有的数字。我猜你真正想说的是第一个字符必须是字母字符,后续字符可以是字母数字。表达方式是:
[a-z][a-z0-9]*
为什么我没有包括范围A-Z
?因为我会为正则表达式设置不区分大小写的标志(?i)
。这也意味着我可以通过不必同时测试or
和来简化不同运算符的测试OR
。
您还使用不需要转义的反斜杠转义了许多字符,例如分号。
最终的正则表达式是:
(?i) # Turn on case-insensitive flag
[a-z][a-z0-9]* # Match alpha followed by 0 or more alphanumeric characters
\s+ # Match one or more white space characters
(?:co|eq|gt) # Match "co" or "eq" or "gt"
\s* # Match 0 or more white space characters
" # Match a double quote
[^"]* # Match 0 or more non-double quote characters
" # Match a double quote
(?: # Start of a non-capturing group
\s+ # Match one or more white space characters
(?:and|or) # Match "and" or "or"
\s+ # Match one or more white space characters
[a-z][a-z0-9]* # Match a name as before
\s+ # Match 1 or more white space characters
(?:co|eq|gt) # Match an operator as before
\s* # Match 0 or more white space characters
"[^"]*" # Match a string as before
)* # Optional non-capturing group repeated 0 or more times
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class DummyTester {
public DummyTester() {
super();
}
public static void main(String[] args) {
checkRegex("userName eq \"bjensen\""); // returning Matches True
checkRegex("(userName eq \"bjensen\" and familyName co \"O'Malley\")"); // returning matches False
checkRegex("(userName eq \"bjensen\" and familyName co \"O'Malley\" AND userName eq \"bjensen\" AND familyName co \"O'Malley\")"); // returning matches False
}
static String checkRegex(String tester) {
String regex ="(?i)[a-z][a-z0-9]*\\s+(?:co|eq|gt)\\s*\"[^\"]*\"(?:\\s+(?:and|or)\\s+[a-z][a-z0-9]*\\s+(?:co|eq|gt)\\s*\"[^\"]*\")*";
System.out.println("The input regex sis : "+regex);
System.out.println("The input String sis : "+tester);
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(tester);
boolean b = m.find();
System.out.println("finder is : "+ b);
if (b) {
String s = m.group();
System.out.println(s);
return s;
}
return null;
}
}
印刷:
The input regex sis : (?i)[a-z][a-z0-9]*\s+(?:co|eq|gt)\s*"[^"]*"(?:\s+(?:and|or)\s+[a-z][a-z0-9]*\s+(?:co|eq|gt)\s*"[^"]*"*)
The input String sis : userName eq "bjensen"
finder is : true
userName eq "bjensen"
The input regex sis : (?i)([a-z][a-z0-9]*\s+(?:co|eq|gt)\s*"[^"]*"(?:\s+(?:and|or)\s+[a-z][a-z0-9]*\s+(?:co|eq|gt)\s*"[^"]*")*)
The input String sis : (userName eq "bjensen" and familyName co "O'Malley")
finder is : true
userName eq "bjensen" and familyName co "O'Malley"
The input regex sis : (?i)([a-z][a-z0-9]*\s+(?:co|eq|gt)\s*"[^"]*"(?:\s+(?:and|or)\s+[a-z][a-z0-9]*\s+(?:co|eq|gt)\s*"[^"]*")*)
The input String sis : (userName eq "bjensen" and familyName co "O'Malley" AND userName eq "bjensen" AND familyName co "O'Malley")
finder is : true
userName eq "bjensen" and familyName co "O'Malley" AND userName eq "bjensen" AND familyName co "O'Malley"
推荐阅读
- python - 如何在 python 中找到我的计算机音频的分贝级别?
- python - 将 yyyyWn 格式转换为 yyyyww - Python
- string - PowerShell 初学者问题:如何组合形成命令的字符串并在同一脚本中运行命令?
- google-apps-script - 应用程序脚本将多个范围从一张工作表复制到另一个电子表格
- r - R 函数来获得回归的 R 平方和 p 值
- google-sheets - 如何通过在 Google 表格上应用 FIFO 方法自动填充“总价”列?
- robotframework - 如何使用 restinstance 库连接到机器人框架中的多个端点
- url - ServiceNow Rest API(使用 PowerBI)
- r - R中的两条线图
- unity3d - 玩家从地板中途跌落,直到碰撞器的外边缘。而不是内边缘