用于替换符号的正则表达式
Posted
技术标签:
【中文标题】用于替换符号的正则表达式【英文标题】:Regular expression for replacing symbols 【发布时间】:2011-11-29 15:29:39 【问题描述】:我正在编写一个可以执行不同 SQL 语句的应用程序(用户将这些语句指定为一个字符串值)。我正在使用 ”;”作为语句之间的分隔符(一次用户可以执行许多 DML 语句)。但是在 DML 语句中可以有一个带有“;”的 varchar 值。里面。
insert into A values(1, 'sda;asdad');
insert into A values(2, 'asdsa');
我的第一个想法是使用String#split(String regex)
。但我不知道如何制作一个正则表达式,它只会帮助那些不在 varchars 中的分号进行拆分。您能建议一种或另一种方法来解决这个问题吗?
【问题讨论】:
【参考方案1】:通常你会通过转义来解决这个问题:
insert into A values(1, 'sda\\;asdad');
然后,当您String#split()
时,请确保 ;
前面没有使用 negative lookbehind 的 \
。像这样的:
String rawInput = ...;
String[] statements = rawInput.split("(?<!\\\\);");
【讨论】:
这是个好主意,但最好让用户不知道必须转义分号,因此他/她必须像在 Oracle SQL developer 或 PL/ 中一样输入 sql 字符串SQL 开发人员 如果没有字符转义,您将基本上开始编写解析器。检查分号是否出现在字符串文字中是不平凡的。【参考方案2】:这是一个简单的解析器,可能正是您要找的。我考虑过使用正则表达式。起初我以为你的语言实际上不是正规的。
我相信 DML 是一种上下文无关语言,但实际上,您的目标语言是常规语言,因为您不关心嵌套语句。您所关心的只是检测***字符串。但是,当您考虑到您的 varchars 中可能存在转义引号时,即使这样也很难使用正则表达式。即如果你有多个 'abcd\'efg'在 varchar 中。
这段代码并不漂亮,但它应该可以满足您的需求。
public static void main(String[] ar)
String s = "aaa 'bb;bb;bb' aaa; aaa 'bb;bb\\';bb' aaa";
System.out.println(splitStatments(s, ';'));
private static List<String> splitStatments(String s, char statementDelimiter)
List<String> statements = new ArrayList<String>();
StringBuffer sb = new StringBuffer();
boolean outsideString = true;
char lastChar = 0;
for (char c : s.toCharArray())
// in the case of the escaped \', we DON'T want to flip the boolean
if (c == '\'' && lastChar != '\\')
outsideString = !outsideString;
if (c == statementDelimiter && outsideString)
statements.add(sb.toString());
sb = new StringBuffer();
else
sb.append(c);
lastChar = c;
if (sb.length() > 0)
statements.add(sb.toString());
return statements;
【讨论】:
【参考方案3】:下面的比String.split
更复杂,但它确实有效:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Regex2
static Pattern pattern = Pattern.compile(".*'(.*);(.*)'.*");
public static void main(String[] args)
String target = "'asdf;asdf';";
String[] split = split(target);
if (split == null)
System.out.println("No match");
else
for (String word : split(target))
System.out.println(word);
static String[] split(String target)
Matcher matcher = pattern.matcher(target);
String[] split = null;
if (matcher.matches())
split = new String[matcher.groupCount()];
for (int i = 1; i <= matcher.groupCount(); i++)
split[i - 1] = matcher.group(i);
return split;
【讨论】:
以上是关于用于替换符号的正则表达式的主要内容,如果未能解决你的问题,请参考以下文章