java - 正则表达式使用分隔符(分号;)分割字符串,但出现在字符串内部的字符串除外

标签 java regex string stringtokenizer

我有一个 Java 字符串,它实际上是一个 SQL 脚本。

CREATE OR REPLACE PROCEDURE Proc
   AS
        b NUMBER:=3;
        c VARCHAR2(2000);
    begin
        c := 'BEGIN ' || ' :1 := :1 + :2; ' || 'END;';
   end Proc;

我想用分号分割脚本,除了出现在字符串内的脚本。 所需的输出是四个不同的字符串,如下所述

1- CREATE OR REPLACE PROCEDURE Proc AS b NUMBER:=3
2- c VARCHAR2(2000)
3- begin c := 'BEGIN ' || ' :1 := :1 + :2; ' || 'END;';
4- end Proc

Java Split() 方法也会将上面的字符串拆分为标记。我想保留这个字符串,因为分号在引号内。

c := 'BEGIN ' || ' :1 := :1 + :2; ' || 'END;';

Java Split()方法输出

1- c := 'BEGIN ' || ' :1 := :1 + :2
2- ' || 'END
3- '

请建议一个正则表达式,它可以用分号分割字符串,但字符串内部的字符串除外。

======================案例2==================== ====

以上部分已得到答复及其工作

这是另一个更复杂的情况

============================================== ==========

我有一个 SQL 脚本,我想标记每个 SQL 查询。每个 SQL 查询由分号 (;) 或正斜杠 (/) 分隔。

1-如果分号或/符号出现在像这样的字符串中,我想转义它们

...WHERE col1 = 'some ; name/' ..

2- 表达式还必须转义任何多行注释语法/*

这里是输入

/*Query 1*/
SELECT
*
FROM  tab t
WHERE (t.col1 in (1, 3)
            and t.col2 IN (1,5,8,9,10,11,20,21,
                                     22,23,24,/*Reaffirmed*/
                                     25,26,27,28,29,30,
                                     35,/*carnival*/
                                     75,76,77,78,79,
                                     80,81,82, /*Damark accounts*/
                                     84,85,87,88,90))
;
/*Query 2*/    
select * from table
/
/*Query 3*/
select col form tab2
;
/*Query 4*/
select col2 from tab3 /*this is a multi line comment*/
/

期望的结果

[1]: /*Query 1*/
    SELECT
    *
    FROM  tab t
    WHERE (t.col1 in (1, 3)
                and t.col2 IN (1,5,8,9,10,11,20,21,
                                         22,23,24,/*Reaffirmed*/
                                         25,26,27,28,29,30,
                                         35,/*carnival*/
                                         75,76,77,78,79,
                                         80,81,82, /*Damark accounts*/
                                         84,85,87,88,90))

[2]:/*Query 2*/    
    select * from table

[3]: /*Query 3*/
    select col form tab2

[4]:/*Query 4*/
    select col2 from tab3 /*this is a multi line comment*/

通过上一篇文章(链接开始)中向我建议的内容已经可以实现一半,但是当注释语法(/*)引入到查询中并且每个查询也可以用正斜杠分隔时(/),表达式不起作用。

最佳答案

正则表达式模式 ((?:(?:'[^']*')|[^;])*); 应该可以满足您的需求。使用 while 循环和 Matcher.find() 提取所有 SQL 语句。像这样的东西:

Pattern p = Pattern.compile("((?:(?:'[^']*')|[^;])*);";);
Matcher m = p.matcher(s);
int cnt = 0;
while (m.find()) {
    System.out.println(++cnt + ": " + m.group(1));
}

使用您提供的示例 SQL,将输出:

1: CREATE OR REPLACE PROCEDURE Proc
   AS
        b NUMBER:=3
2: 
        c VARCHAR2(2000)
3: 
    begin
        c := 'BEGIN ' || ' :1 := :1 + :2; ' || 'END;'
4: 
   end Proc

如果您想获得终止;,请使用m.group(0)而不是m.group(1)

有关正则表达式的更多信息,请参阅 Pattern JavaDoc 和 this great reference 。以下是该模式的概要:

(              Start capturing group
  (?:          Start non-capturing group
    (?:        Start non-capturing group
      '        Match the literal character '
      [^']     Match a single character that is not '
      *        Greedily match the previous atom zero or more times
      '        Match the literal character '
    )          End non-capturing group
    |          Match either the previous or the next atom
    [^;]       Match a single character that is not ;
  )            End non-capturing group
  *            Greedily match the previous atom zero or more times
)              End capturing group
;              Match the literal character ;

关于java - 正则表达式使用分隔符(分号;)分割字符串,但出现在字符串内部的字符串除外,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7430186/

相关文章:

java - Java中通过Arrays.sort对数组进行排序;

java - hibernate中的递归查询

java - 格式化循环输出

Java 正则表达式参数

C# 用正则表达式拆分 string.format 字符串

java - QuickSort (Java) 实现要么溢出,要么停止

c# - C#字符串的$修饰符是什么

string - 算法帮助 : I need help parsing a string that contains * as a wild card in scala

c - c中strtol中参数 'base'的意义是什么?

javascript - 通过 RegEx Javascript 按 2 个字符串分隔符分割