2009-08-26 2 views
1

Мне нужно удалить все теги xml из XML-документа, но сохранить пространство, которое занимают теги, так что текстовое содержимое остается на тех же смещениях, что и в xml. Это должно быть сделано на Java, и я думал, что RegExp будет способом, но я не нашел простого способа получить длину тегов, которые соответствуют моему регулярному выражению.Используйте RegExp для замены тегов XML пробелами (по длине тегов)

В основном то, что я хочу это:

Pattern p = Pattern.compile("<[^>]+>[^<]*]+>"); 
Matcher m = p.matcher(stringWithXMLContent); 
String strippedContent = m.replaceAll("THIS IS A STRING OF WHITESPACES IN THE LENGTH OF THE MATCHED TAG"); 

Надежда кто-то может помочь мне сделать это простым способом!

+3

Почему, о, почему все думают, что регулярные выражения - это решение для всего, что связано с персонажами? :( – Bombe

+1

Потому что большую часть времени это так, правильно?;) – jhoff

ответ

1
Pattern p = Pattern.compile("<[^>]+>[^<]*]+>"); 

В духе вы не можете Parse XML С Regexp, вы знаете, что это не является адекватным шаблон для произвольного XML, правильно? (Совершенно допустимо иметь символ> в значении атрибута, например, не говоря уже о других конструкциях без тегов.)

Я не нашел простого способа получить длину тегов, которые соответствуют моим обычным выражение.

Вместо использования replaceAll повторно нажимайте find на контроллер. Затем вы можете прочитать начало/конец, чтобы заменить индексы, или использовать метод appendReplacement в буфере. например.

StringBuffer b= new StringBuffer(); 
while (m.find()) { 
    String spaces= StringUtils.repeat(" ", m.end()-m.start()); 
    m.appendReplacement(b, spaces); 
} 
m.appendTail(b); 
stringWithXMLContent= b.toString(); 

(StringUtils происходит от Apache Commons. Для более фона и библиотечная свободной альтернатива см this question.)

+0

Спасибо, это точно функциональность Matcher I искали! – jhoff

4

С < и > символы всегда окружают начальные и конечные метки в XML, это может быть проще с помощью простой statemachine. Просто зациклируйте все символы (в некоторой записываемой форме - не сохраняйте в строке), и если вы столкнетесь с флагом < в «режиме замены» и начнете заменять все символы пробелами, пока не встретите >. (Обязательно замените начальное < и закрытие >).

Если вам не нравится макет, вы можете избежать замены символов табуляции и/или символов новой строки. Если все, о чем вы заботитесь, это общая длина строки, это, очевидно, не имеет значения.

Редактировать: Если вы хотите поддерживать комментарии, инструкции по обработке и/или разделы CData, вам также необходимо явно их распознать; Кроме того, значения атрибутов, к сожалению, могут также включать >; все это означает, что полноценная реализация будет более сложной, чем вам хотелось бы.

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

+1

Это в основном работает, но если вы встретите комментарий вокруг некоторых тегов, например.

+0

извините, пропустил сообщение от bobince – 2009-08-27 13:20:41

0
**string**.replaceAll("(</?[a-zA-Z]{1}>)*", "") 

Вы также можете попробовать это. он ищет <, затем/0 или 1, затем следуют символы только 1 (малый или основной символ), затем следует a>, затем * для множественного появления этого шаблона.

:)

Смежные вопросы