2013-03-22 4 views
1

Ищет замену строки на основе регулярного выражения на Java в нижнем прецеденте. Я выполняю обработку XML на основе Groovy и из-за некоторой пользовательской обработки (не будет подробно обсуждаться на этом), в результате XML имеет некоторые недопустимые теги, например.Замена строки на основе Regex Java

<?xml version='1.0' encoding='UTF-8'?> 
<Customer id="xyz" xmlns='http://abc.com'> 
<order orderGroup="mock"> 
    <entry> 
     <key>test</key> 
    </entry> 
</order orderGroup="mock"> 
</Customer id="xyz"> 

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

</order orderGroup="mock"> with </order>, 
</Customer id="xyz"> with </Customer> 

Любая идея, если есть быстрое Java-правило на основе строк, которое я могу использовать для таких замещений?

Спасибо.

+0

Что происходит, когда вы загружаете Javadoc, нажмите Ctrl-F, и тип "регулярное выражение"? Почему бы вам не исправить неисправную «пользовательскую обработку», которая генерирует мусор вместо попыток обхода проблемы? –

ответ

5

попробовать

xml = xml.replaceAll("</([^ >]+).*?>", "</$1>"); 
+0

Удивительный! Это работает отлично. Большое спасибо. – codehammer

+0

+1, но я бы использовал '] +) [^>] +>'. '. *?' - непостоянный друг; зачем ставить себя на произвол судьбы, когда вы можете так легко сказать, что хотите? –

+0

Я согласен о \\ с, но это, кажется, регулярное выражение преобразует "" -> "" –

2

Самое простое решение - исправить вашу пользовательскую обработку XML и заставить ее генерировать действительный XML.

Простое решение - использовать что-то вроде JTidy для очистки вашего XML.

Если вы должны использовать регулярное выражение, вы можете попробовать что-то вроде этого:

Pattern pattern = Pattern.compile("</([A-Za-z]+) [^>]+>"); 
Matcher matcher = pattern.matcher(xml); 

if(matcher.find()) { 
    xml = matcher.replaceAll(matcher.group(1)); 
} 

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

Объяснение регулярное выражение:

<   -> The opening angle bracket of the tag 
/  -> The/that marks a closing tag 
(  -> Start of a capturing group. We want to capture the actual ending tag. 
[A-Za-z]+ -> One or more alphabetic characters (upper and lowercase) 
)   -> End of the capturing group. 
      -> A space. 
[^>]+  -> One or more of anything that is not a closing angle-bracket. 
>   -> The closing angle bracket of the tag. 
+0

Спасибо Vivin! Это работает до некоторой степени. Только проблема заключается в том, что он заменяет даже начальные и конечные угловые скобки. Другими словами, это приводит к клиенту, а не к codehammer

+0

Как показывает [ответ Евгения] (http://stackoverflow.com/a/15581822/20938), это решение гораздо более подробное, чем должно быть. В частности, никогда не нужно вызывать 'find()' перед выполнением подстановки. 'replaceAll()' делает это сам, и если нет совпадений, он возвращает исходную строку без изменений. Вам также не нужно вызывать методы, подобные 'group (n)' для строки замены. Если в строке появятся какие-либо вопросительные знаки или обратные косые черты, вы получите исключение во время выполнения; это не проблема, если вы используете '' $ 1''. –

+0

Да, его ответ намного лучше. –

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