Заменить выражение в границах текста - PullRequest
4 голосов
/ 05 мая 2009

У меня довольно раздражающая проблема, которую я решил с помощью простого рекурсивного метода в Java. Тем не менее, я ищу лучший способ сделать это.

Первоначальная проблема заключалась в наличии пробелов в заголовке Mime в формате Quoted Printable / Base64, который, как я читал в спецификации RFC 2047, запрещен. Это означает, что декодирование не выполняется для заголовка MIME при наличии пробела, например

=?iso-8859-1?Q?H=E4 ll and nothing?=

или более уместно:

=?iso-8859-1?Q?H=E4 ll?= preserve this text =?iso-8859-1?Q?mo nk ey?=

Цель состоит в том, чтобы удалить только пробел между =? ? = границы (или перекодировать, используя 20). Другой текст вне этого должен быть сохранен.

Я ищу альтернативные подходы к решению этой проблемы. Моим целевым языком является Java. Какие-нибудь идеи относительно самого простого, самого чистого подхода к этому?

Ответы [ 4 ]

2 голосов
/ 05 мая 2009

Вы могли бы построить простой конечный автомат для отслеживания, если вы находитесь между =? и? =, затем прочитайте входной символ с помощью символа и выведите его с помощью символа, преобразуя пробельные символы при необходимости ...

0 голосов
/ 05 мая 2009

Ну, я не знаю о лучшем, но вот альтернативный подход:

    public static void main( String[] args )
    {
        String ex1 = "=?iso-8859-1?Q?H=E4 ll?= " + 
            "preserve this text =?iso-8859-1?Q?mo nk ey?=";
        String res1 = removeSpaces( ex1 );

        System.out.println( ex1 );
        System.out.println();
        System.out.println( res1 );
    }

    public static String removeSpaces( String str )
    {
        StringBuffer result = new StringBuffer();
        String strPattern = "(\\?.+\\?)";
        Pattern p = Pattern.compile( strPattern );
        Matcher m = p.matcher( str );

        if ( !m.find() || m.groupCount() == 0 )
        { // Contains no matching sequence.
            return str;
        }

        for ( int i = 1; i <= m.groupCount(); i++ )
        {
            m.appendReplacement( result, 
                m.group( i ).replaceAll( "\\s", "" ) );
        }

        return result.toString();
    }
0 голосов
/ 05 мая 2009

Вы можете разбить строку на?, Затем соединить ее, чередуя заменяющие пробелы, а не.

Редактировать: Упс. Пропустил знак равенства. Буду исправлять.

Редактировать 2: исправленная реализация (производная от примера Javadoc для Matcher.appendReplacement ()):

String input = "=?iso-8859-1?Q?H=E4 ll?= what about in this case? :) =?iso-8859-1?Q?mo nk ey?=";

Pattern p = Pattern.compile("=\\?(.*?)\\?=");
Matcher m = p.matcher(input);
StringBuffer sb = new StringBuffer();
while (m.find()) {
    m.appendReplacement(sb, m.group().replaceAll(" ", ""));
}
m.appendTail(sb);
System.out.println(sb.toString());
0 голосов
/ 05 мая 2009

Регулярные выражения http://java.sun.com/docs/books/tutorial/essential/regex/.

\ s = пробел
\ S = без пробелов
\? = экранированный знак вопроса
, = все символы, подобные * в более слабом сопоставлении с образцом.

Может быть проще всего найти и заменить несколько частей, используя что-то вроде этого: Вытащите эту часть: = \?. \? =

Глобально заменить \ s в этой части пустой строкой.

Поставьте деталь обратно.

Возможно, вы сможете перейти к одному поиску и заменить, если будете играть с регулярным выражением достаточно долго ...

...