Java模式/匹配器

时间:2014-11-05 21:54:34

标签: java regex pattern-matching

这是示例文字:\1f\1e\1d\020028。我无法修改输入文本,我正在从文件中读取长串文本。


我想提取以下内容:\1f\1e\1d\02

为此,我编写了以下正则表达式模式:"\\[a-fA-F0-9]"

我正在使用PatternMatcher类,但我的匹配器无法使用提到的正则表达式找到该模式。我已经使用一些在线正则表达式网站上的文本测试了这个正则表达式,并且令人惊讶的是它在那里工作。

我哪里错了?

原始代码:

public static void main(String[] args) {
    String inputText = "\1f\1e\1d\02002868BF03030000000000000000S023\1f\1e\1d\03\0d";
    inputText        = inputText.replace("\\", "\\\\");

    String regex     = "\\\\[a-fA-F0-9]{2}";

    Pattern p = Pattern.compile(regex);
    Matcher m = p.matcher(inputText);

    while (m.find()) {
        System.out.println(m.group());
    }
}

输出:没有打印

4 个答案:

答案 0 :(得分:2)

您需要正确阅读文件并替换' \'带有' \\'的字符。假设您的项目中有一个名为test_file的文件,其中包含以下内容:

\1f\1e\1d\02002868BF03030000000000000000S023\1f\1e\1d\03\0d

以下是读取文件和提取值的代码:

public static void main(String[] args) throws IOException, URISyntaxException {        
    Test t = new Test();
    t.test();
}

public void test() throws IOException {        
    BufferedReader br =
        new BufferedReader(
            new InputStreamReader(
                getClass().getResourceAsStream("/test_file.txt"), "UTF-8"));
    String inputText;

    while ((inputText = br.readLine()) != null) {
        inputText = inputText.replace("\\", "\\\\");

        Pattern pattern = Pattern.compile("\\\\[a-fA-F0-9]{2}");
        Matcher match = pattern.matcher(inputText);

        while (match.find()) {
            System.out.println(match.group());
        }
    }
}

答案 1 :(得分:2)

(OP添加更多细节后答案已更改)

你的字符串

String inputText = "\1f\1e\1d\02002868BF03030000000000000000S023\1f\1e\1d\03\0d";

实际上不包含任何\文字,因为根据3.10.6. Escape Sequences for Character and String Literals \xxx部分中的Java语言规范,将被解释为Unicode表中的索引字符,其中表示octal (base/radix 8)xxx部分。

示例\123 = 1 * 8 2 + 2 * 8 1 + 3 * 8 0 = 1 * 64 + 2 * 8 + 3 * 1 = 64 + 16 + 3 = 83 代表character S

如果您在问题中提出的字符串在文本文件中写得完全相同,那么您应该将其写为

String inputText = "\\1f\\1e\\1d\\02002868BF03030000000000000000S023\\1f\\1e\\1d\\03\\0d";

(使用转义\,现在代表文字)。


(我的答案的旧版本)

如果没有看到你的代码,很难说出你到底做错了什么。您应该能够找到至少\1\1\1\0,因为您的正则表达式可以匹配一个\和一个十六进制字符。

无论如何,您可以找到您提到的问题的结果:

String text = "\\1f\\1e\\1d\\020028";
Pattern p = Pattern.compile("\\\\[a-fA-F0-9]{2}");
//                                          ^^^--we want to find two hexadecimal 
//                                               characters after \
Matcher m = p.matcher(text);
while (m.find())
    System.out.println(m.group());

输出:

\1f
\1e
\1d
\02

答案 2 :(得分:0)

尝试添加。最后,如:

\\[a-fA-F0-9].

答案 3 :(得分:0)

如果您不想修改输入字符串,可以尝试以下方法:

static public void main(String[] argv) {

            String s = "\1f\1e\1d\020028";
            Pattern regex = Pattern.compile("[\\x00-\\x1f][0-9A-Fa-f]");
            Matcher match = regex.matcher(s);
            while (match.find()) {
                    char[] c = match.group().toCharArray();
                    System.out.println(String.format("\\%d%s",c[0]+0, c[1])) ;
            }
    }

是的,它并不完美,但你明白了。