Java 正则表达式回顾

Java regex lookbehind

我想在两个 "json".

之间匹配具有 "json"(出现超过 2 次)且没有字符串 "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" 在它之间。 在学习了 regex lookbehind 之后,我是这样写 regex 的:

select.*json.*?(?<!from)json.*from.*

我正在使用正则表达式回顾来排除 from 字符串。

但是经过测试,我发现这个正则表达式也匹配字符串"select get_json_object from get_json_object"。

我的正则表达式有什么问题?任何建议表示赞赏。

您需要使用 tempered greedy token 来实现此目的。使用这个正则表达式,

\bjson\b(?:(?!\bfrom\b).)+\bjson\b

此表达式 (?:(?!\bfrom\b).)+ 将匹配任何不包含 from 的文本。

Regex Demo

为了匹配整行,你可以使用,

^.*\bjson\b(?:(?!\bfrom\b).)+\bjson\b.*$

就像您在 post 中想要的那样,只要找到一个 from 未出现在两个 jsons[=36 之间的字符串,此正则表达式就会匹配该行=]

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