用户输入格式:
[fieldname1]比较器[fieldvalue1,fieldvalue2,value3],[fieldname2] 比较器[fieldvalue1,value2,..],..
需要将其解析为:
1. [fieldname1]比较器[fieldvalue1,fieldvalue2,value3]
2. [fieldname2]比较器[fieldvalue1,value2,..]等等
(即)每个字段及其比较器和值必须分开。 而比较器将是以下任何一种:
< = |> = | = |是|< |> | startswith |开始于| Beginswith |开始于|结束 与|的endsWith |
包含
我使用的正则表达式:
([()+。?](\ S)(小于= |> = | = |是|< |> | startswith |开始 与| Beginswith |开始|结束 与|的endsWith |包含)(\ S) [?()+](\)*)
示例: [公司]包含[abc,efg],[email]包含[cdf,test] 正确解析上面没有问题。
问题: 当字段名称或字段值包含符号“[”或“]”时,解析出错。
示例: [company]包含[ab [] c,efg],[email]包含[siva,test]
上面有效,但是因为[]用作分隔符,所以它会停止解析,直到[company]包含[ab []但我希望它能正确解析,例如,
1. [company]包含[ab [] c,efg]
2. [email]包含[siva,test]
感谢。
答案 0 :(得分:0)
您可以尝试使用此正则表达式:
,(?=(?:(?:[^\\[\\]]*[\\]\\[]){2})*[^\\[\\]]*$)
拆分目标字符串应该为您提供拆分结果集的列表。您可以轻松地应用比较器匹配
final String regex = ",(?=(?:(?:[^\\[\\]]*[\\]\\[]){2})*[^\\[\\]]*$)";
final String string = "[company] contains [ab[]c,efg],[email] contains [siva,test]";
String[] res=string.split(regex);
System.out.println(Arrays.asList(res).toString());
通过使用此方法,您可以获得已删除的结果。您可能需要检查的是,如果每个索引包含您显示的正确比较器。如果没有,那么从阵列中删除它。
以上代码输出:
[
[company] contains [ab[]c,efg],
[email] contains [siva,test]
]
说明:
每当找到a时,>
,(?=(?:(?:[^\\[\\]]*[\\]\\[]){2})*[^\\[\\]]*$)
正向前看会一直运行到字符串末尾,其中包含以下行
(?:[^\\[\\]]*[\\]\\[]){2})*
确保 - 如果找到括号,则会发现两次。然后最后一个*表示0或更多重复的括号对。
为什么这很重要?从任何逗号开始,然后计算[和]括号的数量。如果之后只有偶数个括号,您将看到只需要用该逗号分隔。并且你不想分开逗号,之后有奇数括号。这就是解释。
对于正则表达式的完整细分,您可以查看右上方逐个字符给出完整解释的链接。
答案 1 :(得分:0)
所以基本上你需要在,
和]
之间的每个[
分割字符串。
如果您使用谷歌的番石榴,您可以使用Splitter
并使用正面的]
和正面的背后[
String s = "[fieldname1] comparator [fieldvalue1,fieldvalue2,value3],[fieldname2] comparator [fieldvalue1,value2]";
Pattern stringPattern = Pattern.compile("(?<=\\]),(?=\\[)");
Iterable<String> split = Splitter.on(stringPattern).omitEmptyStrings().split(s);
split.forEach(System.out::println);
答案 2 :(得分:0)
首先,我们必须定义一个与名称匹配的正则表达式,另一个匹配比较器的正则表达式,以及与值匹配的第三个正则表达式:
private static final String NAME_RE = "[A-Za-z0-9_]+";
private static final String VALUE_RE = "[A-Za-z0-9_\\[\\]\\.]+";
private static final String COMPARATOR_RE
= "<=|>=|=|is|<|>|startswith|Starts with|Beginswith|Begins with|Ends with|Endswith|Contains";
我们现在可以创建组合这些子正则表达式的模式:
private static final String RE = "\\s*\\[(" + NAME_RE + ")\\]\\s*"
+ "(" + COMPARATOR_RE + ")\\s*\\[\\s*("
+ VALUE_RE + "(?:\\s*,\\s*" + VALUE_RE + ")*)\\s*\\]"
+ "(?:\\s*,\\s*(.*))?";
private static final Pattern PATTERN
= Pattern.compile(RE, Pattern.CASE_INSENSITIVE);
请注意,它匹配单个规则,该规则可能会或可能不会跟随逗号和其他规则。
解析源字符串必须迭代规则:
private static void parse(String source) {
String s = source;
while (s != null) {
Matcher matcher = PATTERN.matcher(s);
if (!matcher.matches()) {
throw new IllegalArgumentException("Invalid syntax: " + source);
}
String name = matcher.group(1);
String comparator = matcher.group(2);
String values = matcher.group(3);
s = matcher.group(4);
System.out.println("[" + name + "] " + comparator + " [" + values + "]");
}
}
现在让我们尝试解析你的两个例子:
private static final String EXAMPLE1 = "[company] contains [abc,efg],[email] contains [cdf,test]";
private static final String EXAMPLE2 = "[company] contains [ab[]c,efg],[email] contains [siva,test]";
public static void main(String[] args) {
parse(EXAMPLE1);
parse(EXAMPLE2);
}
它产生以下输出:
[company] contains [abc,efg]
[email] contains [cdf,test]
[company] contains [ab[]c,efg]
[email] contains [siva,test]
更新:
请注意,必须限制值的内容,因为如果“efg]”和“[email]包含[cdf”都是可接受的值,则无法知道这些示例是否由一个或两个规则组成
更新2:
这是VALUE_RE的一个非常宽松的正则表达式:
private static final String VALUE_RE
= "[^,\\[\\]]*(?:\\[[^,\\[\\]]*\\][^,\\[\\]]*)*";
这里的值不能包含任何逗号,只能包含平衡括号,不能嵌套。