Java 正则表达式 : Trying to convert oracle || to CONCAT()

标签 java regex

我有一堆 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 字。

但是,在某些特殊情况下,正则表达式可能就足够了。划分并解决问题可能会更容易,例如

  1. 转换 (SELECT|,) <content> ||(SELECT|,) concat(<content> ||

  2. 转换 || <content> <field> (FROM|,), <content>) <field> (FROM|,

  3. 转换所有剩余的||到,

存储每个阶段后的结果并将规则应用于该中间转换。

类似

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/

相关文章:

java - 将庞大数据集添加到 Oracle 数据库中

python - 如果 re.findall 找不到匹配项,如何返回字符串

c# - 另一个 URL 前缀正则表达式问题(用于 C#)

java - 如何确定一个字符串是否是另一个字符串的子序列而不考虑其间的字符?

java - 消息聊天不太好用

java - 在 android 派中重新启动应用程序时,sqlite 中输入的数据会自动删除

python - 使用 findall() 方法解析简单的数学方程

java - 使用@ElementCollection、@MapKeyJoinColumn 进行多对多关系时引用关键问题

c# - 检查结果中是否存在正则表达式组

c# - 提取链接正则表达式 c#