【问题标题】:Java RegEx not replacing all expected patternsJava RegEx 没有替换所有预期的模式
【发布时间】:2019-11-06 20:51:26
【问题描述】:

我想要实现的只是用 ILIKE 替换比较等于,而不是赋值语句。

SELECT * FROM db WHERE SUBJECT_TYPE = 'Person';

应该替换为

SELECT * FROM db WHERE SUBJECT_TYPE ILIKE 'Person';

然而

SET session ABC.VAR = 5;

应该保持不变。

为此,我尝试使用前瞻,以便在 equals (=) 之前没有 SET

Java

String str = "SELECT * FROM db WHERE SUBJECT_TYPE = 'Person' AND PREDICATE = 'name' AND OBJECT_VALUE = 'John' AND VERSION = '0' "
final Pattern EQUALS_ILIKE_PATTERN = Pattern.compile("(?i)((^((?!SET)[^=])+?)\\s*)=");

final Matcher matcher = EQUALS_ILIKE_PATTERN .matcher(str);

while (matcher.find())
{
    final String fromString = matcher.group(0);

    str = matcher.replaceAll("$1 ILIKE");
}

System.out.println(str);

实际结果:

SELECT * FROM db WHERE SUBJECT_TYPE ILIKE 'Person' AND PREDICATE = 'name' AND OBJECT_VALUE = 'John' AND VERSION = '0'

预期结果:

SELECT * FROM db WHERE SUBJECT_TYPE ILIKE 'Person' AND PREDICATE ILIKE 'name' AND OBJECT_VALUE ILIKE 'John' AND VERSION ILIKE '0'

这里的实际结果并没有替换所有必要的等号 (=)。

【问题讨论】:

    标签: java sql regex


    【解决方案1】:

    我们可以通过单线电话String#replaceAll 来做到这一点:

     String str = "SELECT * FROM db WHERE SUBJECT_TYPE = 'Person' AND PREDICATE = 'name' AND OBJECT_VALUE = 'John' AND VERSION = '0' ";
    str = str.replaceAll("(WHERE|AND)\\s+(\\S+)\\s+=(?=\\s*'[^'+]+')", "$1 $2 ILIKE");
    System.out.println(str);
    

    此输出(为便于阅读而格式化):

    SELECT *
    FROM db
    WHERE
        SUBJECT_TYPE ILIKE 'Person' AND
        PREDICATE ILIKE 'name' AND
        OBJECT_VALUE ILIKE 'John' AND
        VERSION ILIKE '0'
    

    【讨论】:

    • 这个正则表达式不会处理赋值的事情,即包含'SET'的那个。
    • 更新为仅针对 WHERE 子句。现在SET 子句将不会更新。
    • 我并不真正关心 WHERE|AND ,只是想否定 SET。另外我想知道为什么我的正则表达式不适用于这个?
    • (?!SET)零宽度 负前瞻。在前瞻之后你永远不会真正匹配任何内容,所以它没有多大意义。如果您想要一个更强大的解决方案,您将不得不编写一个 SQL 解析器,所以我不会再次更新我的答案。
    • 您想至少用有效的解决方案更新答案吗?
    猜你喜欢
    • 2016-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多