Заменить выражение в границах текста
Вопрос
У меня довольно раздражающая проблема, которую я решил с помощью простого рекурсивного метода в 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. Есть идеи о простейшем и чистом подходе к этому?
Решение
Вы могли бы построить простой конечный автомат для отслеживания, если вы находитесь между =? и? =, затем прочитайте входной символ с помощью символа и выведите его с помощью символа, преобразуя пробельные символы при необходимости ...
Другие советы
Регулярные выражения http://java.sun.com/docs/ книги / учебник / важно / регулярное выражение / .
\ s = пробел
\ S = без пробелов
\? = экранированный знак вопроса
, = все символы, подобные * в более слабом сопоставлении с образцом.
Может быть проще всего найти и заменить несколько частей, используя что-то вроде этого: Вытащите эту часть: = \?. \? =
Глобально замените \ s в этой части пустой строкой.
Поставьте деталь обратно.
Возможно, вы сможете перейти к одному поиску и заменить его, если будете играть с регулярным выражением достаточно долго ...
Ну, я не знаю лучше, но есть альтернативный подход:
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();
}
Вы можете разбить строку на?, а затем собрать ее обратно, чередуя заменяющие пробелы, а не.
Редактировать: упс. Пропустил знак равенства. Исправлю.
Редактировать 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());