Java 在逗号上拆分存在转义引号时在引号外拆分,或在括号外拆分

Java 在逗号上拆分存在转义引号时在引号外拆分,或在括号外拆分,java,string,split,Java,String,Split,是否可以使用以下条件拆分字符串 除以(即逗号) 在每个元素上,忽略检查第一个“和最后一个”中的逗号 在每个元素上,忽略检查第一个(和最后一个)中的逗号 e、 g 前两个要点可通过以下方式实现: 这在使用SQL进行操作时非常有用。例如,拆分项目、追加、插入、预编项目等 提前谢谢。我知道这有点长,但相当直截了当,只需记录有多少个参数和内部或外部引用 String[] splitElements(String source) { int parencount = 0; boolea

是否可以使用以下条件拆分字符串

  • 除以(即逗号)
  • 在每个元素上,忽略检查第一个“和最后一个”中的逗号
  • 在每个元素上,忽略检查第一个(和最后一个)中的逗号
e、 g

前两个要点可通过以下方式实现:

这在使用SQL进行操作时非常有用。例如,拆分项目、追加、插入、预编项目等


提前谢谢。

我知道这有点长,但相当直截了当,只需记录有多少个参数和内部或外部引用

String[] splitElements(String source) {
    int parencount = 0;
    boolean q = false;
    List<String> l = new ArrayList<>();
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < source.length(); i++) {
        char c = source.charAt(i);
        switch (c) {
            case ',':
                if (!q && parencount == 0) {
                    l.add(sb.toString());
                    sb.setLength(0);
                } else {
                    sb.append(c);
                }
                break;

            case '(':
                if(!q) parencount++;
                sb.append(c);
                break;

            case ')':
                if(!q) parencount--;
                sb.append(c);
                break;

            case '\'':
                q = ! q;
                sb.append(c);
                break;

            default:
                sb.append(c);
                break;
        }
    }
    String last = sb.toString();
    l.add(last);
    String sa[] = l.toArray(new String[l.size()]);
    return sa;
}
String[]拆分元素(字符串源){
int-parencount=0;
布尔q=false;
列表l=新的ArrayList();
StringBuilder sb=新的StringBuilder();
对于(int i=0;i
您可以将java类的方法
String
与此

Regex:

(?<!\([^\(\)']{0,100}),(?![^\(\)']*\))(?=(?:'[^']*'|[^'])*$)
(?<!\([^\(\)']{0,100}),(?![^\(\)']*\))
public class Main{

    public static void main(String[] args) {

        String source = "to_char(DATE, 'YYYY,MM,DD'), to_char(DATE, ('YYYY(MM,DD)')), " +
                        "to_char(DATE, ('YYYY,MM,DD)')), to_char(DATE, ('YYYY(MM,DD')), " +
                        "NAME, to_char(DATE, '(YYYY)MM,DD'), CITY || ', (UK)', " +
                        "CITY || ', US''s CITY', CITY || ', UK', " +
                        "'I am sad :(', to_char(DATE, 'YYYY,MM,DD')";

        String delimiters = "(?<!\\([^\\(\\)']{0,100}),(?![^\\(\\)']*\\))(?=(?:'[^']*'|[^'])*$)";

        String[] tokens = source.split(delimiters);

        for(String token : tokens) {
            System.out.println(token.trim());
        }
    }
}
to_char(DATE, 'YYYY,MM,DD')
to_char(DATE, ('YYYY(MM,DD)'))
to_char(DATE, ('YYYY,MM,DD)'))
to_char(DATE, ('YYYY(MM,DD'))
NAME
to_char(DATE, '(YYYY)MM,DD')
CITY || ', (UK)'
CITY || ', US''s CITY'
CITY || ', UK'
'I am sad :('
to_char(DATE, 'YYYY,MM,DD')
使用lookahead可确保从
到字符串末尾(regex:
(?:'[^']*')*$
)计数的
'
的数量为偶数,或者直到字符串末尾(regex:
[^']*$)为止有由任何字符组成的字符串(regex:
[^']*$

策略:

(?<!\([^\(\)']{0,100}),(?![^\(\)']*\))(?=(?:'[^']*'|[^'])*$)
(?<!\([^\(\)']{0,100}),(?![^\(\)']*\))
public class Main{

    public static void main(String[] args) {

        String source = "to_char(DATE, 'YYYY,MM,DD'), to_char(DATE, ('YYYY(MM,DD)')), " +
                        "to_char(DATE, ('YYYY,MM,DD)')), to_char(DATE, ('YYYY(MM,DD')), " +
                        "NAME, to_char(DATE, '(YYYY)MM,DD'), CITY || ', (UK)', " +
                        "CITY || ', US''s CITY', CITY || ', UK', " +
                        "'I am sad :(', to_char(DATE, 'YYYY,MM,DD')";

        String delimiters = "(?<!\\([^\\(\\)']{0,100}),(?![^\\(\\)']*\\))(?=(?:'[^']*'|[^'])*$)";

        String[] tokens = source.split(delimiters);

        for(String token : tokens) {
            System.out.println(token.trim());
        }
    }
}
to_char(DATE, 'YYYY,MM,DD')
to_char(DATE, ('YYYY(MM,DD)'))
to_char(DATE, ('YYYY,MM,DD)'))
to_char(DATE, ('YYYY(MM,DD'))
NAME
to_char(DATE, '(YYYY)MM,DD')
CITY || ', (UK)'
CITY || ', US''s CITY'
CITY || ', UK'
'I am sad :('
to_char(DATE, 'YYYY,MM,DD')
  • 使用负向前看、负向后看以确保
    超出
    (…)
  • 使用lookahead确保前面只有一对从
    开始计数到字符串末尾的
  • 代码示例:

    (?<!\([^\(\)']{0,100}),(?![^\(\)']*\))(?=(?:'[^']*'|[^'])*$)
    
    (?<!\([^\(\)']{0,100}),(?![^\(\)']*\))
    
    public class Main{
    
        public static void main(String[] args) {
    
            String source = "to_char(DATE, 'YYYY,MM,DD'), to_char(DATE, ('YYYY(MM,DD)')), " +
                            "to_char(DATE, ('YYYY,MM,DD)')), to_char(DATE, ('YYYY(MM,DD')), " +
                            "NAME, to_char(DATE, '(YYYY)MM,DD'), CITY || ', (UK)', " +
                            "CITY || ', US''s CITY', CITY || ', UK', " +
                            "'I am sad :(', to_char(DATE, 'YYYY,MM,DD')";
    
            String delimiters = "(?<!\\([^\\(\\)']{0,100}),(?![^\\(\\)']*\\))(?=(?:'[^']*'|[^'])*$)";
    
            String[] tokens = source.split(delimiters);
    
            for(String token : tokens) {
                System.out.println(token.trim());
            }
        }
    }
    
    to_char(DATE, 'YYYY,MM,DD')
    to_char(DATE, ('YYYY(MM,DD)'))
    to_char(DATE, ('YYYY,MM,DD)'))
    to_char(DATE, ('YYYY(MM,DD'))
    NAME
    to_char(DATE, '(YYYY)MM,DD')
    CITY || ', (UK)'
    CITY || ', US''s CITY'
    CITY || ', UK'
    'I am sad :('
    to_char(DATE, 'YYYY,MM,DD')
    

    您介意再举一个第二和第三个要点的例子吗?不要使用
    sb=new StringBuilder()
    重置生成器,只需调用
    sb.setLength(0)
    。如果引号中有右括号,至少就正确的SQL语法而言,这会有问题。@WillShackleford感谢您的回答。问题是,在“”中可能有任意数量的,其中一些可能没有匹配的右括号。带有不平衡括号字符的字符串文字将抛出逻辑。如果(!q),则添加
    if
    round
    parencount++
    parencount--
    @WillShackleford如果你不介意讨论括号不匹配的问题,我会编辑输入。非常感谢。你的答案也适用于我所有的测试用例。我不得不说这真的很聪明。谢谢你也让解释得这么清楚。请注意这个d无法解决拆分“'I am sad:(',to_char(DATE,'YYYY,MM,DD')”,你介意看一看我们是否可以改进解决方案吗?非常感谢Hanks。这非常有效。我还用这个方案更新了原始帖子。是的,它仍然有效。我认为没有,但我错了。谢谢Hanks。我已经测试了你的两个解决方案。我试图接受你的两个解决方案,但Stackoverflow不允许我为此:(