有正则表达式忽略新行,只匹配整个大字符串?

时间:2010-08-25 20:50:37

标签: java regex

我在这里有这个字符串:

CREATE UNIQUE INDEX index555 ON
SOME_TABLE
(
    SOME_PK          ASC
);

我希望在多行中匹配并匹配SQL语句(所有这些都会在1个大字符串中有很多)......就像这样,但我只是在CREATE UNIQUE INDEX index555 ON上匹配

(CREATE\s.+;)

注意:如果重要的话,我正在尝试在java中完成此任务。

5 个答案:

答案 0 :(得分:17)

编译正则表达式时需要使用DOTALL和MULTILINE标志。这是一个Java代码示例:

import java.util.regex.*;

public class test
{
    public static void main(String[] args)
    {
        String s =
        "CREATE UNIQUE INDEX index555 ON\nSOME_TABLE\n(\n    SOME_PK          ASC\n);\nCREATE UNIQUE INDEX index666 ON\nOTHER_TABLE\n(\n    OTHER_PK          ASC\n);\n";

        Pattern p = Pattern.compile("([^;]*?('.*?')?)*?;\\s*", Pattern.CASE_INSENSITIVE | Pattern.DOTALL | Pattern.MULTILINE);

        Matcher m = p.matcher(s);

        while (m.find())
        {
        System.out.println ("--- Statement ---");
        System.out.println (m.group ());
        }
    }
}

输出将是:

--- Statement ---
CREATE UNIQUE INDEX index555 ON
SOME_TABLE
(
    SOME_PK          ASC
);

--- Statement ---
CREATE UNIQUE INDEX index666 ON
OTHER_TABLE
(
    OTHER_PK          ASC
);

答案 1 :(得分:8)

检查this

  

正则表达式。匹配除行终止符以外的任何字符,除非指定了DOTALL标志

所以你需要做这样的事情

Pattern p = Pattern.compile("your pattern", Pattern.DOTALL);

答案 2 :(得分:5)

DOTALL标记可让.匹配换行符,但如果您只是将其应用于现有的正则表达式,则最终会匹配从第一个CREATE到最后一个;的所有内容。 {1}}一气呵成。如果您想单独匹配语句,则需要执行更多操作。一种选择是使用非贪婪量词:

Pattern p = Pattern.compile("^CREATE\\b.+?;",
    Pattern.DOTALL | Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);

我还使用MULTILINE标志让^锚点在换行符后匹配,而CASE_INSENSITIVE因为SQL至少是我听说过的每种口味。请注意,所有三个标志都有“内联”形式,您可以在正则表达式中使用它们:

Pattern p = Pattern.compile("(?smi)^CREATE\\b.+?;");

(由于历史原因,DOTALL的内联形式为s;它在Perl中称为“单行”模式,它起源于此。)另一种选择是使用否定的字符类:

Pattern p = Pattern.compile("(?mi)^CREATE\\b[^;]+;");

[^;]+匹配除;之外的任何字符中的一个或多个 - 包括换行符,因此不需要s标记。

到目前为止,我假设每个语句都以一行的开头开头,并以分号结尾,如您的示例所示。我不认为SQL标准需要这些东西,但我希望你知道在这种情况下你是否可以依赖它们。您可能希望在单词边界而不是行边界处开始匹配:

Pattern p = Pattern.compile("(?i)\\bCREATE\\b[^;]+;");

最后,如果您正在考虑使用正则表达式和SQL执行更复杂的操作,不要。用正则表达式解析SQL是一个愚蠢的游戏 - 它比HTML和正则表达式更糟糕。

答案 3 :(得分:3)

查看可传递给Pattern.compile的各种标志。我认为DOTALL是你需要的。

答案 4 :(得分:3)

您需要使用Pattern.DOTALL标记来匹配各行。