Java模式/匹配器
这是一个示例文本:Java模式/匹配器,java,regex,pattern-matching,Java,Regex,Pattern Matching,这是一个示例文本:\1f\1e\1d\020028。我无法修改输入文本,我正在从文件中读取长字符串文本 我想提取以下内容:\1f,\1e,\1d,\02 为此,我编写了以下正则表达式模式:“\\[a-fA-F0-9]” 我正在使用Pattern和Matcher类,但是我的Matcher无法使用前面提到的正则表达式找到模式。我已经在一些在线正则表达式网站上用文本测试了这个正则表达式,令人惊讶的是,它在那个里工作 我哪里做错了 原始代码: 输出:未打印任何内容请尝试添加一个。最后,比如: \\[a
\1f\1e\1d\020028
。我无法修改输入文本,我正在从文件中读取长字符串文本
我想提取以下内容:
\1f
,\1e
,\1d
,\02
为此,我编写了以下正则表达式模式:“\\[a-fA-F0-9]”
我正在使用Pattern
和Matcher
类,但是我的Matcher无法使用前面提到的正则表达式找到模式。我已经在一些在线正则表达式网站上用文本测试了这个正则表达式,令人惊讶的是,它在那个里工作
我哪里做错了
原始代码:
输出:未打印任何内容请尝试添加一个。最后,比如:
\\[a-fA-F0-9].
您需要正确读取文件并将“\”字符替换为“\ \”。假设项目中有一个名为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());
}
}
}
(OP添加更多详细信息后,答案已更改)
你的绳子
String inputText = "\1f\1e\1d\02002868BF03030000000000000000S023\1f\1e\1d\03\0d";
实际上不包含任何\
文本,因为根据\xxx
节中的Java语言规范,将被解释为Unicode表中的字符索引,其值由xxx
部分表示
示例\123
=1*82+2*81+3*80=1*64+2*8+3*1=64+16+3=83,表示
如果您在问题中呈现的字符串在文本文件中写得完全相同,那么您应该将其写为
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
如果不想修改输入字符串,可以尝试以下操作:
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])) ;
}
}
是的,这并不完美,但你明白了。我猜你的一些反斜杠是在逃避你不想做的事情。不过,您必须向我们展示您的实际代码,以便我确定。
\\[a-fA-F0-9]
查找后跟一个字母或数字的反斜杠。我想您应该查找反斜杠后跟两个字母或数字。我想你能想出办法解决这个问题。输入字符串的格式正确吗?我想应该是“\\1f\\1e\\1d\\020028”。为了帮助您更轻松,请张贴代码示例,说明如何使用此正则表达式。这是输入文件中的文本吗?我们能看看你是怎么读的吗?还有,当你打印红色的东西时,你看到了什么?你的代码确实有效。但是,当我做了类似的事情时,正如你在上面看到的,它不起作用。问题是转义输入字符串。检查更新。我使用了apache commons lang中的StringEscapeUtils。@bullzeye解释escapeJava
将返回Unicode表示,而不是八进制表示,因此您将得到\u0001
或\u0000
,这就是为什么需要替换(“\\u000”,“\\”
)(将字符串中类似的\u0001
转换为\1
)@bullzeye无论如何,这种方法失败了,例如在\03
的情况下,因为它基于这样的假设,即对于八进制值,只有\x
,而不是\xx
那些可能表示大于15的值,需要使用两个十六进制字符来编写,这将使转义返回\u00XX
@bullzeye此方法也不会转义由\123
表示的字符(83
十进制->'S'
字符)因为它是Java语言中使用的普通字符,不需要转义。谢谢!这个解决方案可以部分工作。对于我在修改后的答案中提到的输入字符串,以下是输出:'\1f\1e\1d\160\1f\1e\1d\0d'您提到的代码可以工作。但是,当我做了类似于您上面看到的事情时,它不工作。
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])) ;
}
}