Как сопоставить «escape» непечатаемый символ в регулярном выражении? - PullRequest
1 голос
/ 01 октября 2011

Я нашел инструкции, http://answers.oreilly.com/topic/214-how-to-match-nonprintable-characters-with-a-regular-expression/, но ни один из кодов \ e, \ x1b, \ x1B не работает для меня в Java.

EDIT

Я пытаюсь заменить управляющие последовательности ANSI (в частности, цветовые последовательности) вывода команды терминала Linux. В Python шаблон замены будет выглядеть как "\ x1b [34; 01m", что означает синий жирный текст. Этот же шаблон не работает в Java. Я попытался заменить "[34; 01m" отдельно, и это сработало, поэтому проблема \ x1b. И я выполняю экранирование "[" с помощью Pattern.quote ().

EDIT

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);

EDIT Вот код, с которым я закончил:

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 / Теперь проблема в том, что я получаю исключение NullPointerException, если я пытаюсь соответствовать Pattern.quote("[01;34m"). Все отлично соответствует, кроме строк, которые содержат [, хотя я их цитирую. Исключение составляют следующие:

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)

EDIT

Итак, согласно http://java.sun.com/developer/technicalArticles/releases/1.4regex/, символ перехода должен соответствовать "\u001B", что действительно работает в моем случае. Проблема в том, что если я использую tokens.put("\u001B" + Pattern.quote("[01;34m"), "qwe");, я все равно получаю вышеупомянутый NPE.

Ответы [ 4 ]

1 голос
/ 01 октября 2011

quote() - создать шаблон, который будет соответствовать входной строке дословно .В вашей строке есть язык шаблонов.Посмотрите на вывод quote () - вы увидите, что он пытается буквально найти четыре символа \ x1b.

0 голосов
/ 22 декабря 2012

FWIW, я работал над извлечением цветовых кодов ANSI из цветных файлов log4j, и этот маленький паттерн, похоже, подходит для всех случаев, с которыми я сталкивался:

Pattern.compile("(\\u001B\\[\\d+;\\d+m)+")
0 голосов
/ 11 ноября 2011

Правильное значение символа "escape" в регулярном выражении: \u001B

0 голосов
/ 01 октября 2011

escape-последовательности ANSI имеют следующую форму [\ 033 [34; 01m]

, где \ 033 - это символ ANSI 033 (октавный) или 1b в шестнадцатеричном или 27 в десятичном виде,Вам необходимо использовать следующее регулярное выражение:

Pattern p = Pattern.compile("\033\\[34;01m");

Вы можете использовать восьмеричное (\ 033) или шестнадцатеричное (\ x1b) представление, когда вы используете непечатаемый символ в строке java.

...