2017-02-21 11 views
2

Я хочу собрать весь блок с начального названия до конечного названия, но не включать заголовок конца. Примером может служить:Как сопоставить блок от начала до конца с использованием регулярного выражения

<section1> 
Base_Currency=EUR 
Description=Revaluation 
Grouping_File 
<section2> 

результат матча должен быть:

<section1> 
Base_Currency=EUR 
Description=Revaluation 
Grouping_File 

Проблема заключается в том, что как я могу сформулировать шаблон для этого матча с помощью Regex в Java?

+0

regexr.com помогает мне много в таких ситуациях. Это также дает вам чит-лист. – Midnightas

+0

не могли бы вы привести пример? – QSY

ответ

1

Если вход что-то вроде ниже

<section1> 
Base_Currency=EUR 
Description=Revaluation 
Grouping_File 
<section2> 
Base_Currency=EUR 
Description=Revaluation 
Grouping_File 
<section3> 
Base_Currency=EUR 
Description=Revaluation 
Grouping_File 

Тогда вы можете используйте следующее регулярное выражение

(?s)(<section\d+>.*?)(?=<section\d+>|$) 

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

NODE      EXPLANATION 
-------------------------------------------------------------------------------- 
    (?s)      set flags for this block (with . matching 
          \n) (case-sensitive) (with^and $ 
          matching normally) (matching whitespace 
          and # normally) 
-------------------------------------------------------------------------------- 
    (      group and capture to \1: 
-------------------------------------------------------------------------------- 
    <section     '<section' 
-------------------------------------------------------------------------------- 
    \d+      digits (0-9) (1 or more times (matching 
          the most amount possible)) 
-------------------------------------------------------------------------------- 
    >      '>' 
-------------------------------------------------------------------------------- 
    .*?      any character (0 or more times (matching 
          the least amount possible)) 
-------------------------------------------------------------------------------- 
)      end of \1 
-------------------------------------------------------------------------------- 
    (?=      look ahead to see if there is: 
-------------------------------------------------------------------------------- 
    <section     '<section' 
-------------------------------------------------------------------------------- 
    \d+      digits (0-9) (1 or more times (matching 
          the most amount possible)) 
-------------------------------------------------------------------------------- 
    >      '>' 
-------------------------------------------------------------------------------- 
    |      OR 
-------------------------------------------------------------------------------- 
    $      before an optional \n, and the end of 
          the string 
-------------------------------------------------------------------------------- 
)      end of look-ahead 

Если вы хотите, чтобы соответствовать только для одного тега, то вы можете использовать

(?s)(<section\d+>[^<]*) 

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

NODE      EXPLANATION 
-------------------------------------------------------------------------------- 
    (?s)      set flags for this block (with . matching 
          \n) (case-sensitive) (with^and $ 
          matching normally) (matching whitespace 
          and # normally) 
-------------------------------------------------------------------------------- 
    (      group and capture to \1: 
-------------------------------------------------------------------------------- 
    <section     '<section' 
-------------------------------------------------------------------------------- 
    \d+      digits (0-9) (1 or more times (matching 
          the most amount possible)) 
-------------------------------------------------------------------------------- 
    >      '>' 
-------------------------------------------------------------------------------- 
    [^<]*     any character except: '<' (0 or more 
          times (matching the most amount 
          possible)) 
-------------------------------------------------------------------------------- 
)      end of \1 
2

Если все входа этого формата, вы можете просто раскол:

String[] sections = input.split("\\R(?=<)"); 

\R является «любой символ новой строки последовательности» и (?=<) означает «следующий символ является '<'».

Однако если это не так, то из регулярных выражений панели инструментов вы будете нуждаться:

  • DOTALL флага так точка соответствует новой строке слишком
  • MULTILINE флага так ^ матчи начинаются линии слишком
  • отрицательный взгляд вперед, чтобы вы перестанете потреблять в начале следующего раздела

Если предположить, что «секции» начать ш Ith "<" в начале строки:

"(?sm)^<\\w+>(.(?!^<))*" 

Вот как вы можете использовать его:

String input = "<section1>\nBase_Currency=EUR\nDescription=Revaluation\nGrouping_File\n<section2>\nfoo"; 
Matcher matcher = Pattern.compile("(?sm)^<\\w+>(.(?!^<))*").matcher(input); 
while (matcher.find()) { 
    String section = matcher.group(); 
} 

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

  • Нет связанных вопросов^_^