我想匹配一个字符串,其中包含“json”(出现次数超过2次),并且在两个“json”之间没有字符串“from”。
For example(what I want the string match or not):
select json,json from XXX -> Yes
select json from json XXXX -> No
select json,XXXX,json from json XXX -> Yes
为什么第三个是匹配的,因为我只想要两个“json”字符串在它之间没有“from”。在学习正则表达式后,我写这样的正则表达式:
select.*json.*?(?<!from)json.*from.*
我正在使用正则表达式lookbehind除了字符串。
但经过测试,我发现这个正则表达式匹配字符串“select get_json_object from get_json_object”。
我的正则表达式有什么问题?任何建议表示赞赏。
您需要使用tempered greedy token来实现此目的。使用这个正则表达式,
\bjson\b(?:(?!\bfrom\b).)+\bjson\b
这个表达式(?:(?!\bfrom\b).)+
将匹配任何不包含from
的文本作为其中的整个单词。
为了匹配整条线,你可以使用,
^.*\bjson\b(?:(?!\bfrom\b).)+\bjson\b.*$
就像你想要的帖子一样,这个正则表达式将匹配该行,只要它找到一个字符串,其中from
不出现在两个json
s之间
Regex Demo with full line match
编辑:为什么OP的正则表达式select.*json.*?(?<!from)json.*from.*
没有按预期工作
你的正则表达式开始与select
匹配,然后.*
尽可能匹配,同时确保它找到json
前面跟着一些可选字符然后再次期望找到json
字符串然后.*
再次匹配一些字符然后期望找到一个from
,最后使用.*
零个或多个可选字符。
我们来看一个应该匹配的示例字符串。
select json from json json XXXX
它有两个没有json
的from
字符串,所以它应该匹配,但它不匹配,因为在你的正则表达式中,json和from的顺序或存在是固定的,这是json
然后json
然后from
,这不是这个字符串中的情况。
这是一个Java code demo
List<String> list = Arrays.asList("select json,json from XXX","select json from json XXXX","select json,json from json XXX","select json from json json XXXX");
list.forEach(x -> {
System.out.println(x + " --> " + x.matches(".*\\bjson\\b(?:(?!\\bfrom\\b).)+\\bjson\\b.*"));
});
打印,
select json,json from XXX --> true
select json from json XXXX --> false
select json,json from json XXX --> true
select json from json json XXXX --> true