将变量作为正则表达式传递

时间:2021-03-14 17:39:10

标签: java regex

我有这个代码:

private boolean setListOfRegex() {
    try {
        listRegex = new ArrayList<Pattern>();
        tokens = new ArrayList<String[]>();
        String[] regs = regexFile.split("\n");
        for (int i = 0; i < regs.length; i++) {
            String[] info = regs[i].split(";");
            Pattern p = Pattern.compile(info[0]);
            listRegex.add(p);
            String[] a = { info[1], info[2] };
            tokens.add(a);
        }
        return true;
    } catch (Exception e) {
        System.out.println(e.getMessage());
        return false;
    }

数组regsregexFile的数组结果,其中regexFile是一个.txt文件,如下所示:

\\+|\\*|\\*\\*|\\-|\\=;OPERATOR;0
\\w+\s\\=;VARIABLE;1
\\(;OPEN_BRACKET;2
\\);CLOSE_BRACKET;3
[0-9]+;NUMBER;4

该功能工作正常,但问题在于该行:

Pattern p = Pattern.compile(info[0]);

当我更改 info[0]"\\\\(" 时,它工作正常,但变量没有,我打印 info[0],它显示相同的字符串,所以当我使变量显示此错误:

Unclosed group near index 3 
\\\\(

似乎把括号像一些正则表达式的括号一样。我认为这是因为 info[0] 应该是 "\\\\\\\\\("。我尝试使用该表达式,但错误仍然存​​在:

Unclosed group near index 5 
\\\\(

如何在"\\\\("中保存表达式info[0]。在这之前的两个表达式:

\\+|\\*|\\*\\*|\\-|\\=;OPERATOR;0
\\w+\s\\=;VARIABLE;1

编译正常

2 个答案:

答案 0 :(得分:2)

<块引用>

当我将 info[0] 更改为“\\(”时,它工作正常,但是使用 变量没有

这是不正确的。

演示:

public class Main {
    public static void main(String[] args) {
        Pattern.compile("\\\\(");
    }
}

输出:

Exception in thread "main" java.util.regex.PatternSyntaxException: Unclosed group near index 3
\\(
...

正如预期的那样,行为保持不变

public class Main {
    public static void main(String[] args) {
        String str = "\\\\(";
        Pattern.compile(str);
    }
}

输出:

Exception in thread "main" java.util.regex.PatternSyntaxException: Unclosed group near index 3
\\(
...

这种行为的原因

字符串 \\\\( 表示 \ 后跟未转义的 (,正则表达式引擎将其解释为组的开始。这是因为 \\\\ 被正则表达式引擎解释为单个 \ - 一个 \ 转义 \,然后 \\ 转义转义 {{1 }} 就像用 \ 转义 [

因此,您需要 \\[ 来转义 \\,因此您的字符串应该是 (,其中 \\\\\\( 指定转义的 \\\\\指定转义的 \\(

演示:

(

答案 1 :(得分:0)

文件内容 \\( 相当于 Java 字符串文字 "\\\\(",即两个(文字)反斜杠后跟一个左括号。要在正则表达式中转义元字符,需要在它前面加上一个反斜杠。这包括反斜杠字符本身,它可以用另一个前面的反斜杠进行转义。

如果您不能修改文件,那么您必须在将它们编译为正则表达式之前删除重复的反斜杠并用单个反斜杠替换它们:

// replace 2 literal backslash character with a single literal backslash character:
info[0] = info[0].replace("\\\\", "\\");