检查JDBC String / VARCHAR比较中的转义%?

时间:2013-04-03 08:34:33

标签: java sql regex jdbc

我正在编写一个JDBC库,它接受来自用户输入的 java.lang.String 对象并发出JDBC SELECT 语句。我希望非转义字符的存在可以引导库在比较中使用 LIKE 子句,而对于没有未转义字符的字符串,应该使用更严格的 = 比较。

E.g。使用下表和数据:

CREATE TABLE S (V CHARACTER VARYING);
INSERT INTO S (V) VALUES ('%B%'); -- row a
INSERT INTO S (V) VALUES ('%%%'); -- row b
INSERT INTO S (V) VALUES ('%%X'); -- row c

我希望字符串“\%\%\%”* (其中不包含未转义的字符)导致以下查询:

SELECT * FROM S WHERE V = '%%%'

...只匹配1行(第b行)。字符串“\ %% \%”(其中包含一个未转义的)应该会导致查询:

SELECT * FROM S WHERE V LIKE '\%%\%'

...只匹配行a和b(但没有c)。

是否有Java中的实用程序类对未转义的字符进行此类测试,并生成 = 比较所需的非转义版本(当所有时) %字符最初是否已转义?)

逻辑应该如下:

 if ( unescapedPercentageExists( s ) )
     likeClause( s )
 else
     equalClause ( removeEscapes( s ) )

2 个答案:

答案 0 :(得分:2)

试试正则表达式

public static boolean unescapedPercentageExists(String s){
    return s.matches(".*((?<=[^\\\\])|^)%.*");
}

测试:

abc: false
abc\%: false
\%abc: false
a\%bc: false
abc%: true
%abc: true
a%bc: true

答案 1 :(得分:0)

不使用正则表达式并使用转义“\”字符的解决方案如下所示,我将结果与Arun解决方案并列,并使用 DIFF突出显示!“\\%”等字符串的情况下的正确行为。可悲的是,它使用了一个神奇的字符串:

import java.io.IOException;
import java.io.File;
import java.util.List;
import org.apache.commons.lang3.StringEscapeUtils;

public class FooMain {

    private static boolean unescapedPercentageExists(String s) {
        return s.matches(".*((?<=[^\\\\])|^)%.*");
    }

    private static String RARE_STRING="use a rare string, @#$645k";

    private static String replacePerc(String s) {
        return s.replace("%", "n"+RARE_STRING);
    }

    private static boolean unescapedPercentageExists2(String s) {
        return StringEscapeUtils.unescapeJava(replacePerc(s)).indexOf("n"+RARE_STRING)!=-1;
    }


    public static void main(String args[]) throws IOException {
        List<String> testStrs = // read from file to avoid having to escape them as literals (I leave this out as I use one of my utility classes)
        System.out.println("showing if unescaped percentage exists");
        for (String testStr : testStrs) {
            boolean ver1 = unescapedPercentageExists(testStr);
            boolean ver2 = unescapedPercentageExists2(testStr);
            System.out.println(String.format("%10s ver1: %5b ver2: %5b %s",
                                   testStr, ver1, ver2, ver1==ver2?"":"DIFF!"));
        }
    }
}

它产生:

showing if unescaped percentage exists
       abc ver1: false ver2: false 
     abc\% ver1: false ver2: false 
     \%abc ver1: false ver2: false 
     a\%bc ver1: false ver2: false 
      abc% ver1:  true ver2:  true 
      %abc ver1:  true ver2:  true 
      a%bc ver1:  true ver2:  true 
         % ver1:  true ver2:  true 
        \% ver1: false ver2: false 
       \\% ver1: false ver2:  true DIFF!
      \\\% ver1: false ver2: false 
     \\\\% ver1: false ver2:  true DIFF!