2013-04-03 52 views
1

我在寫一個JDBC庫,它接受來自用戶輸入的java.lang.String對象併發出JDBC SELECT語句。我想轉義人物的存在導致庫使用LIKE子句中的比較,而絃樂沒有轉義字符嚴格=比較應該被使用。檢查JDBC String/VARCHAR比較中的轉義百分比?

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行)。而String 「\ %% \%」(其中包含一個轉義)應導致查詢:

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

...這將只匹配行A和B(但沒有C) 。

有沒有在Java工具類做這種測試的轉義字符和生成必要的=比較轉義的版本(當所有字符開始逃跑?)

應儘可能的邏輯如下:

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

回答

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 
+0

它不涉及逃逸\字符情況下工作。例如。以下字符串序列:%,\%,\\%,\\\%,\\\\%將產生:true,false,false,false,false應該是:true,false,true,false ,真的。 –

0

,我對並列阿倫的解決方案的結果,不使用正則表達式,並逃脫「\」字符的工作原理是以下與DIFF高亮顯示A解決方案!正確行爲的情況下字符串如「\\%」。可悲的是,它採用了特殊的字符串:

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!