2013-07-13 8 views
1

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

Давая файл XML, который выглядит следующим образом:

<?xml version="1.0" encoding="UTF-8"?> 
<databaseChangeLog> 

    <include file="init.changelog.xml"/> 
    <include file="v9.1.changelog.xml"/> 
    <include file="v9.2.changelog.xml"/> 
    <include file="v9.3.changelog.xml"/> 
    <include file="v9.3.1.changelog.xml"/> 
    <include file="v9.3.3.changelog.xml"/> 

</databaseChangeLog> 

Я хотел бы иметь регулярное выражение, которое бы извлечь последнюю версию файла журнала изменений. В приведенном выше примере будет строка v9.3.3

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

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

+3

Regex очень, очень плохой выбор для разбора XML. – dasblinkenlight

+0

Попробуйте использовать [XML-парсер] (http://stackoverflow.com/questions/373833/best-xml-parser-for-java) – BLaZuRE

+0

Тот факт, что это XML, здесь не очень уместен. Все, что мне нужно, - это быстрый способ получить последнее значение между Я знаю о других способах синтаксического анализа XML, но не стоит пытаться принести другую зависимость просто для этого. – Julian

ответ

0

Попробуйте следующее:

xmlString = xmlString.replace("\r", "").replace("\n", ""); 
String version = xmlString.replaceAll("^.*(v\\d+(\\.\\d+)*)[^\\d]+$","$1"); 
+0

Спасибо, но это не будет выбирать ** init * * строка в том случае, если ** ** будет последней строкой.Я постараюсь адаптировать – Julian

1

Вы можете прочитать файл в виде строки, то используйте Pattern и Matcher классов, здесь приведен пример

String target = "...<include file=\"init.changelog.xml\"/><include file=\"v9.1.changelog.xml\"/><include file=\"v9.3.3.changelog.xml\"/></databaseChangeLog>..."; 
    Pattern pattern = Pattern.compile("(v)((\\d\\.)+)|init"); 
    Matcher matcher = pattern.matcher(target); 
    String version = ""; 
    while (matcher.find()) 
    { 
     version = matcher.group(); 
     System.out.println(version); 
    } 
    // use version 

Выражение (v) ((\\ d \ \.) + | init): означает соответствие строки, состоящей из буквы v, за которой следует целое число (\\ d), за которым следует точка (\\.) и + означает один или более

'|' является оператором Or-ing, так что вы также можете сопоставить «init»

, когда часть шаблона, включенного в две круглые скобки, означает, что они образуют одну группу, вам полезно поместить шаблон в виде групп, чтобы сделать это легко, если вы хотите получить одну группу отдельно от сопоставленной строки с помощью шаблона Matcher

«matcher» будет соответствовать любой части строки, которая соответствует шаблону, matcher.group() получит эту часть, сопоставленную со всей строкой , вы также можете использовать matcher.group (i), чтобы получить группу из сопоставленной строки

например, здесь matcher.group (2) будет отображать только цифры и точки без буквы «v» и следить за тем, чтобы она 1 индекс прежде чем 0 целая часть соответствует от целевой строки, она работает так же на matcher.group()

+0

Я не думаю, что я был достаточно ясен. Как вызывается файл, не ограничивается vdd.d.d.changelog.xml. Это просто наше соглашение, но ничто не помешало бы кому-то назвать их файл примерно так: ** ** В этом случае, если это последний, включите запись в этом файле нам нужно записать строку ** fix_jira_bug_2014 ** – Julian

+0

humm, не знаю, будет ли «.chagelog» тоже не все время, но я догадался, что он всегда будет если да, то что насчет примерно такого: 'int end = target.lastIndexOf (". changelog "); int start = target.lastIndexOf ("\" ", end);' –

+0

и получить результат от 'target.substring (start + 1, end)', который получит слово между include и .changelog независимо от того, –

0

Вот один вкладыш:

String lastVersion = input.replaceAll("(?s).*include file=\"(.*?)\"/>[\n\\s]*</databaseChangeLog", "$1"); 
+0

Это очень похоже на тот, который я добавлен в качестве части моего последнего комментария Саре Тарек. \ n не требуется, так как \ s также содержит новые строки. Однако это не будет работать, если то, что это не пространство добавляется между changelog.xml "/> и <включаемый файл =" v9.3.3.changelog.xml "/> -> Julian

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