正则表达式从插入查询中提取值

时间:2016-08-10 11:25:29

标签: java regex

我们说我有这个问题

INSERT INTO `TABLENAME` VALUES(xxx,yyy,zzz);

我使用以下方法单独提取值

public String extractValues(String queryLine){
    return queryLine.substring(queryLine.indexOf('(') + 1,queryLine.lastIndexOf(')'));
}

但后来我意识到Insert query可以采取以下形式,

INSERT INTO `TABLENAME` VALUES(xxx,yyy,zzz),(aaa,bbb,ccc);

我现在如何提取值?

我想regex可能),(是要在INSERT INTO `TABLENAME` VALUES(xxx,yyy,zzz),(aaa,'bb(,)b',ccc); 上进行分割的方式,但这似乎不对。如果其中一个值有那些,那该怎么办?因此我不确定。

请指导。

案例I正在努力处理

xxx,yyy,zzz and aaa,'bb(,)b',ccc

必填项: var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]; Array.from(document.getElementsByClassName('cell')).forEach(function(e, i) { e.textContent = arr[Math.round(Math.random()*(arr.length-1))]; }); function columnCount(columnIndex, value) { var count = 0; // For each row, get the n-th span, $(".table .row span:nth-child(" + (columnIndex+1) + ")").each(function(i,e) { if (e.innerHTML == value) count++; }); return count; } function rowCount(rowIndex, value) { var count = 0; $(".table .row:nth-child(" + (rowIndex+1) + ") span").each(function(i,e) { if (e.innerHTML == value) count++; }); return count; } function allCount(value) { var count = 0; $(".table .row span").each(function(i,e) { if (e.innerHTML == value) count++; }); return count; } console.log("allCount(6): " + allCount(6)); console.log("columnCount(0, 6): " + columnCount(0,6)); console.log("rowCount(0, 6): " + rowCount(0,6));

P.S:值之间的逗号无关紧要

4 个答案:

答案 0 :(得分:2)

您只需编写代码即可:

public String[] extractValues(String queryLine){
    String valuesRaw = queryLine.substring(queryLine.indexOf("VALUES(") + 7,  queryLine.lastIndexOf(");"));
    return valuesRaw.split("\\),\\(");
}

所有这些都应该像现在一样工作,除了你必须处理一个字符串数组而不是一个普通的字符串。

无需regexps。

<强>更新

您可以检查插入字符串是否包含可能破坏该方法的序列。

这是一个包含enanched代码的测试类:

public class Test {

    public String[] extractValues(String queryLine){
        String valuesRaw = queryLine.substring(queryLine.indexOf("VALUES(") + 7,  queryLine.lastIndexOf(");"));

        if (valuesRaw.indexOf("),(") > -1) {
            valuesRaw = valuesRaw.replaceAll("'([^\\(\\)]*)\\),\\(([^\\(\\)]*)'", "'$1#SEPARATOR#$2'");
            String[] values = valuesRaw.split("\\),\\(");
            int i = 0;
            for (String value : values) {
                if (value.indexOf("#SEPARATOR#") > -1) {
                    values[i] = value.replace("#SEPARATOR#", "),(");
                }
                i++;
            }
            return values;
        } else {
            return valuesRaw.split("\\),\\(");
        }
    }

    public static void main(String[] args) {

        Test t = new Test();

        String[] allQueryStrings = new String[] {
                "INSERT INTO `TABLENAME` VALUES(xxx,yyy,zzz);",
                "INSERT INTO `TABLENAME` VALUES(xxx,yyy,zzz),(aaa,bbb,ccc);",
                "INSERT INTO `TABLENAME` VALUES(xxx,yyy,zzz),(aaa,'bb(,)b',ccc);",
                "INSERT INTO `TABLENAME` VALUES(xxx,yyy,zzz),(aaa,'bb),(b',ccc);"
        };

        for (String queryString : allQueryStrings) {

            System.out.println(queryString);

            for (String values : t.extractValues(queryString)) {
                System.out.println(values);
            }

        }

    }

}

答案 1 :(得分:1)

尝试使用正则表达式\(.*?,.*?,.*?\) 编辑:尝试正则表达式\(.+?,.+?,.+?\)

答案 2 :(得分:1)

通过这种方案一般可以解决支持字面文字的某种模式(必须从识别中排除):

  • 找到并替换你在char文字中搜索的模式,例如'b),(bb'应该变为'b ### bb'
  • 对修改后的字符串执行识别
  • 恢复char文字中的模式,所以'b ### b'应该返回'b),(bb'

我不知道如何使用单个语句或单个正则表达式来完成此操作。为了这个论点,我写了下面的代码。

import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ValuesListParse {

  public static void main(String[] args) {

    String stmt = " INSERT INTO `TABLENAME` VALUES(xxx,yyy,zzz),(aaa,'bb),(b',ccc),(aaa,bbb,ccc); ";
    System.out.printf("%s\n", stmt);

    //extract values list
    stmt = stmt.split("(?i)\\s+values\\s*\\(|\\);")[1];
    System.out.printf("values list: %s\n", stmt);

    // identify pattern between '' (char literal) and replace it with another pattern: the 2nd group is what we want 
    /* UPDATE modified regexp from ('.*)(\\)\\,\\()(.*') to ('\\w*)(\\)\\,\\()+(\\w*') to manage multiple literals containig the pattern */
    Matcher m = Pattern.compile("('\\w*)(\\)\\,\\()+(\\w*')").matcher(stmt);
    while (m.find()) {
        stmt = stmt.substring(0, m.start(2)) + "###" + stmt.substring(m.end(2), stmt.length());
        System.out.printf("values list with pattern subst inside char literal: %s\n", stmt);
    }

    // split multiple values
    String[] multiValues = stmt.split("\\)\\,\\(");

    // adjust char literal
    for (int i = 0; i < multiValues.length ; i++) {
        multiValues[i] = multiValues[i].replaceAll("###", "),(");
    }

    System.out.println(Arrays.toString(multiValues));

   }
}

答案 3 :(得分:0)

您可以使用arrA = [{id:2, name:'b'}]; 之类的内容查找所有匹配项。