当文本用双引号括起时,转义文本中的特殊字符

时间:2016-02-15 09:23:21

标签: java regex

我正在编写一个正则表达式来逃避一些特殊字符,包括输入中的双引号。

输入可以用双引号括起来,并且不应该转义。

输入结果:

"te(st", te(st, te"st 

预期产出:

"te\(st", te\(st, te\"st

使用的代码:

String regex = "^\".*\"$";
    String value = "\"strin'g\"";
    Pattern SPECIAL_REGEX_CHARS = Pattern.compile("[()'"\\[\\]*]");

    if (Pattern.matches(regex, value)){
        String val = value.substring(1, value.length() -1);
        String replaceAll = SPECIAL_REGEX_CHARS.matcher(val).replaceAll("\\\\$0");
        replaceAll = "\""+replaceAll+"\"";
        System.out.println(replaceAll);
    }else {
        String replaceAll = SPECIAL_REGEX_CHARS.matcher(value).replaceAll("\\\\$0");
        System.out.println(replaceAll);
    }

1 - 检查文本是否用双引号括起来。如果是,则转义用双引号括起来的文本中的特殊字符。

2 - 否则。转义文本中的特殊字符。

任何可以组合#1和#2的正则表达式?

此致 阿尼尔

2 个答案:

答案 0 :(得分:0)

仅使用一个转义正则表达式的简单解决方案

您可以使用if (s.startsWith("\"") && s.endsWith("\""))检查字符串是否同时包含前导",如果是,则可以使用{{删除前导{和{1}} 1}},然后使用转义的正则表达式转义,然后再添加"。否则,只需要逃避集合中的角色。

replaceAll("^\"|\"$", "")

查看另一个IDEONE demo

使用""回调"

的替代解决方案

以下是使用替换的一个正则表达式的方法:

String SPECIAL_REGEX_CHARS = "[()'\"\\[\\]*]";
String s = "\"te(st\""; // => "te\(st"
String result;
if (s.startsWith("\"") && s.endsWith("\"")) {
    result = "\"" + s.replaceAll("^\"|\"$", "").replaceAll(SPECIAL_REGEX_CHARS, "\\\\$0") + "\"";
}
else {
    result = s.replaceAll(SPECIAL_REGEX_CHARS, "\\\\$0");
}
System.out.println(result.toString());

请参阅IDEONE demo

要点:

  • Matcher#addReplacement() Matcher#appendTail()允许操纵群组。
  • appendReplacement正则表达式与2个备用分支结合使用:String SPECIAL_REGEX_CHARS = "[()'\"\\[\\]*]"; //String s = "\"te(st\""; // => "te\(st" //String s = "te(st"; // => te\(st String s = "te\"st"; // => te\"st StringBuffer result = new StringBuffer(); Matcher m = Pattern.compile("(?s)\"(.*)\"|(.*)").matcher(s); if (m.matches()) { if (m.group(1) == null) { // we have no quotes around m.appendReplacement(result, m.group(2).replaceAll(SPECIAL_REGEX_CHARS, "\\\\\\\\$0")); } else { m.appendReplacement(result, "\"" + m.group(1).replaceAll(SPECIAL_REGEX_CHARS, "\\\\\\\\$0") + "\""); } } m.appendTail(result); System.out.println(result.toString()); 匹配以(?s)\"(.*)\"|(.*)开头并以".*"结尾的字符串(请注意"是DOTALL内联修饰符允许匹配字符串与换行符序列)或"替代匹配所有其他字符串。
  • 如果第一个选项匹配,我们只需替换第一个捕获组中选定的特殊字符,然后在两端添加(?s)
  • 如果匹配第二个备选方案,只需在整个第2组中添加转义符号。
  • 要使用文字反斜杠替换,您需要在替换模式中使用.*

答案 1 :(得分:0)

您可以使用negative lookbehind and lookahead

mydomain.com/privateurl.html?userid=123562

这实质上是这样说:转义字符类System.out.println(value.replaceAll("([()'\\[\\]*]|(?<!^)\"(?!$))", "\\\\$0")); 中的任何内容,或任何前面没有字符串开头或后跟字符串结尾的[()'\[\]*]

唯一的问题是,无论在另一端是否有相应的报价,都会忽略前导和尾随报价。如果这是一个问题,您可以链接这些替换以逃避不匹配的前导或尾随引用:

"