首页 > 解决方案 > 如何用单个正则表达式模式替换过多的 SQL 通配符?

问题描述

我正在创建一个从输入字符串中去除非法通配符模式的函数。如果可能的话,理想的解决方案应该使用单个正则表达式。

非法通配符模式是:%%%_%. 其中的每个实例都应替换为%.

这是问题所在...我正在尝试通过针对各种输入运行该函数来执行一些模糊测试,以尝试实现和破坏它。

它在大多数情况下都有效;但是,对于复杂的输入,它不会。

此问题的其余部分已更新:

以下输入应返回空字符串(不是详尽的列表):

以下输入应返回%(不是详尽的列表)。

在某些情况下,输入中还有其他字符...例如:

我尝试过使用几种不同的模式,但我的测试失败了。

String input = "%_%%%%_%%%_%";

// old method:
public static String ancientMethod1(String input){
    if (input == null)
        return "";
    return input.replaceAll("%_%", "").replaceAll("%%", "");  // Output: ""
}

// Attempt 1:
// Doesn't quite work right.
// "A%%" is returned as "A%%" instead of "A%"
public static String newMethod1(String input) {
    String result = input;
    while (result.contains("%%") || result.contains("%_%"))
        result = result.replaceAll("%%","%").replaceAll("%_%","%");
    if (result.equals("%"))
        return "";
    return input;
}

// Attempt 2:
// Succeeds, but I would like to simplify this:
public static String newMethod2(String input) {
    if (input == null)
        return "";

    String illegalPattern1 = "%%";
    String illegalPattern2 = "%_%";
    String result = input;

    while (result.contains(illegalPattern1) || result.contains(illegalPattern2)) {
        result = result.replace(illegalPattern1, "%");
        result = result.replace(illegalPattern2, "%");
    }

    if (result.equals("%") || result.equals("_"))
        return "";

    return result;
}

这是我如何使用它的更完整定义的示例:https ://gist.github.com/sometowngeek/697c839a1bf1c9ee58be283b1396cf2e

标签: javaregex

解决方案


我不太确定,如果列出的输入可能有其他实例,如果没有,也许带有开始和结束锚点的表达式在这里非常适用,或者一个一个,或者类似于:

^%{1,3}(_%{1,3})?(_%{1,3})?(_%)?$

演示

测试

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

final String regex = "^%{1,3}(_%{1,3})?(_%{1,3})?(_%)?$";
final String string = "%_%\n"
     + "%%\n"
     + "%%_%%\n"
     + "%%%_%%%\n"
     + "%_%%%\n"
     + "%%%_%\n"
     + "%%_%_%\n"
     + "%%_%%%_%%%_%";

final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
final Matcher matcher = pattern.matcher(string);

while (matcher.find()) {
    System.out.println("Full match: " + matcher.group(0));
    for (int i = 1; i <= matcher.groupCount(); i++) {
        System.out.println("Group " + i + ": " + matcher.group(i));
    }
}

正则表达式电路

jex.im可视化正则表达式:

在此处输入图像描述


推荐阅读