我在这里有这个字符串:
CREATE UNIQUE INDEX index555 ON
SOME_TABLE
(
SOME_PK ASC
);
我希望在多行中匹配并匹配SQL语句(所有这些都会在1个大字符串中有很多)......就像这样,但我只是在CREATE UNIQUE INDEX index555 ON
上匹配
(CREATE\s.+;)
注意:如果重要的话,我正在尝试在java中完成此任务。
答案 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标记来匹配各行。