我有一堆 SQL 语句,最初是为了支持 Oracle 而编写的,并且使用了很多特定的 Oracle 语法。使用简单的正则表达式样式查找和替换或通过使用 JDBC 函数可以轻松解决大部分问题。然而,这个案子却给我带来了一些麻烦。
有很多实例将连接用于值,而我正在尝试替换 col1 ||列2 ||如果数据库引擎不是 Oracle,则 col3 将替换为 CONCAT(col1,col2,col3) 样式语法。
我知道使用某种 ORM 是理想的选择,但由于各种原因,这在这种情况下并不实用。
我有一个测试应用程序设置来测试我最有可能接触到的一些情况,但我无法弄清楚如何让它替换所有实例以及 | 之后的可变数量的匹配项。 |。我现在拥有的解决方案仅与最后一次出现的 col||col 匹配。也许这是不可能的,但我想尝试并穷尽这个解决方案路径。
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class regex {
public static void main(String args[]){
String sSource = "SELECT col1, col2||word||default_col||another field1, col3 || ' quote test ' || default_1 field2 FROM table order by 1";
try{
String pattern ="((\\b\\[a-zA-Z0-9_]+|'.*')\\s*(\\|\\|)\\s*(\\w+))";
Pattern p = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE|Pattern.MULTILINE|Pattern.DOTALL);
Matcher m = p.matcher(sSource);
while(m.find()){
sSource = m.replaceAll("CONCAT($2 , $4)");
System.out.println("found match");
}
System.out.println(sSource);
} catch( Exception e) {
System.out.println("Bad things:" + e.getMessage());
}
}
}
最佳答案
你不能真正对所有 || 进行 concat 替换使用正则表达式,因为它们不够强大,无法处理 SQL 语法。您可以使用 || 连接任何内容。包括包含 || 的字 rune 字。
但是,在某些特殊情况下,正则表达式可能就足够了。划分并解决问题可能会更容易,例如
转换
(SELECT|,) <content> ||
至(SELECT|,) concat(<content> ||
转换
|| <content> <field> (FROM|,)
至, <content>) <field> (FROM|,
转换所有剩余的||到,
存储每个阶段后的结果并将规则应用于该中间转换。
类似
private static String identifierOrString = "[a-zA-Z0-9_\\.\\(\\),]+";
public static void main(String[] args) {
String testCase = "SELECT col1, col2||word||default_col||another field1, col3 || ' quote test ' || default_1 field2 FROM table where 'abc' = col4 || col5 || col6 GROUP BY col7 || col8";
testCase = convertBeginnings(testCase);
System.out.println("Phase 1: " + testCase);
testCase = convertEndings(testCase);
System.out.println("Phase 2: " + testCase);
testCase = convertRemainingOperators(testCase);
System.out.println("Finished: " + testCase);
}
private static String convertBeginnings(String testCase) {
return replace("(SELECT|WHERE|=|<>|like|GROUP BY|\\,)(\\s+)(%s|'[^']*')\\s*\\|\\|", testCase, "%s %s concat(%s ||");
}
private static String convertEndings(String testCase) {
return replace("\\|\\|\\s*(%1$s|'[^']*')\\s*(\\s%1$s)?\\s*((\\,|FROM|GROUP BY|ORDER BY|=|<>|like|$))", testCase,",%s) %s %s");
}
private static String replace(String regexp, String source , String target) {
Matcher m = match(regexp, source);
while(m.find()) {
source = source.replace(m.group(0), String.format(target, nvl(m.group(1)), nvl(m.group(2)), nvl(m.group(3))));
}
return source;
}
private static String nvl(String value) {
return null == value ? "" : value;
}
private static String convertRemainingOperators(String testCase) {
return testCase.replaceAll("\\|\\|", ",");
}
private static Matcher match(String regexp, String target ) {
Pattern p = Pattern.compile(String.format(regexp, identifierOrString), Pattern.CASE_INSENSITIVE|Pattern.MULTILINE|Pattern.DOTALL);
return p.matcher(target);
}
关于Java 正则表达式 : Trying to convert oracle || to CONCAT(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4970512/