我找到了一个howto http://answers.oreilly.com/topic/214-how-to-match-nonprintable-characters-with-a-regular-expression/,但是没有代码,\ e,\ x1b,\ x1B,在Java中适合我。
修改
我正在尝试替换Linux终端命令输出的ANSI转义序列(特别是颜色序列)。 在Python中,替换模式看起来像“\ x1b [34; 01m”,这意味着蓝色粗体文本。这种模式在Java中不起作用。我试图分别替换“[34; 01m”,它有效,所以问题是\ x1b。 我我使用Pattern.quote()进行“[”转义。
修改
Map<String,String> escapeMap = new HashMap<String,String>();
escapeMap.put("\\x1b[01;34m", "</span><span style=\"color:blue;font-weight:bold\">");
FileInputStream stream = new FileInputStream(new File("/home/ch00k/gun.output"));
FileChannel fc = stream.getChannel();
MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
String message = Charset.defaultCharset().decode(bb).toString();
stream.close();
String patternString = Pattern.quote(StringUtils.join(escapeMap.keySet(), "|"));
System.out.println(patternString);
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(message);
StringBuffer sb = new StringBuffer();
while(matcher.find()) {
matcher.appendReplacement(sb, escapeMap.get(matcher.group()));
}
matcher.appendTail(sb);
String formattedMessage = sb.toString();
System.out.println(formattedMessage);
修改 的 这是我最终得到的代码:
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.charset.*;
import java.util.*;
import java.util.regex.*;
import org.apache.commons.lang3.*;
class CreateMessage {
public static void message() throws IOException {
FileInputStream stream = new FileInputStream(new File("./gun.output"));
FileChannel fc = stream.getChannel();
MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
String message = Charset.defaultCharset().decode(bb).toString();
stream.close();
Map<String,String> tokens = new HashMap<String,String>();
tokens.put("root", "nobody");
tokens.put(Pattern.quote("[01;34m"), "qwe");
String patternString = "(" + StringUtils.join(tokens.keySet(), "|") + ")";
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(message);
StringBuffer sb = new StringBuffer();
while(matcher.find()) {
System.out.println(tokens.get(matcher.group()));
matcher.appendReplacement(sb, tokens.get(matcher.group()));
}
matcher.appendTail(sb);
System.out.println(sb.toString());
}
}
文件gun.output包含ls -la --color=always /
的输出
现在,问题是如果我试图匹配Pattern.quote("[01;34m")
,我将收到NullPointerException。除了包含[
的字符串之外,所有内容都匹配得很好,即使我引用它们。例外情况如下:
Exception in thread "main" java.lang.NullPointerException
at java.util.regex.Matcher.appendReplacement(Matcher.java:699)
at org.minuteware.jgun.CreateMessage.message(CreateMessage.java:32)
at org.minuteware.jgun.Main.main(Main.java:23)
修改 的
因此,根据http://java.sun.com/developer/technicalArticles/releases/1.4regex/,转义字符应与"\u001B"
匹配,这在我的情况下确实有效。问题是,如果我使用tokens.put("\u001B" + Pattern.quote("[01;34m"), "qwe");
,我仍然会得到上面提到的NPE。
答案 0 :(得分:1)
quote()
用于创建与输入字符串 verbatim 匹配的模式。你的字符串中有模式语言。看看quote()的输出 - 你会发现它试图找到四个字符\ x1b。
答案 1 :(得分:0)
ansi转义序列具有以下形式 [\ 033 [34; 01m]
其中\ 033是ANSI字符033(oct)或1b为十六进制或27为十进制。您需要使用以下正则表达式:
Pattern p = Pattern.compile("\033\\[34;01m");
当您在java字符串中使用不可打印的字符时,可以使用八进制(\ 033)或十六进制(\ x1b)表示。
答案 2 :(得分:0)
正则表达式中“escape”字符的正确值是\u001B
答案 3 :(得分:0)
FWIW,我一直在努力从彩色log4j文件中剥离ANSI颜色代码,这个小模式似乎可以解决我遇到的所有情况:
Pattern.compile("(\\u001B\\[\\d+;\\d+m)+")