Java - Regex - совпадение открывающих и закрывающих фигурных тегов - PullRequest
1 голос
/ 20 марта 2019

Я хочу захватить текст, подобный этому:

{ul}
  {li}Item 1{/li} 
  {li}Item 2{/li} 
  {li}Item 3{/li} 
{/ul}  
{img}this_is_an_image{/img} 
{p}paragraph text {/p} {h2}Heading{/h2}

И превратить его в ArrayList из хэш-карт, например, так:

[
  { "ul" : ["Item 1", "Item 2", "Item 3"] },
  {"img" : "this_is_an_image"}, 
  {"p" : "paragraph text"}, 
  {"h2" : "Heading"}
]

В настоящее время у меня есть цикл while, который можетизвлекать элементы «базового» уровня из строки (т.е. не вложенные элементы).

ArrayList<Object> list = new ArrayList<>();
Pattern pattern = Pattern.compile("\\{(\\w+)}(?:\\()?([^\\{\\)]+)(?:\\{\\/\1})?");
Matcher matches = pattern.matcher(s);
while (matches.find()) {
    Map<String, String> match = new HashMap<>();
    match.put(matches.group(1), matches.group(2));
    list.add(match);
}
return list;

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

Таким образом, чтобы изменить код что-то вроде этого:

ArrayList<Object> list = new ArrayList<>();
Pattern pattern = Pattern.compile("New pattern");
Matcher matches = pattern.matcher(s);
while (matches.find()) {
    Map<String, Object> match = new HashMap<>();
    Pattern patt = Pattern.compile("only capture text within brackets pattern")
    Matcher nestedMatches = patt.matcher(matches.group(2))
    ArrayList<String> sublist = new ArrayList<>();
    while(nestedMatches.find()) {
      sublist.add(nestedMatches.group(2))
    }
    if (list.size() > 0) {
       match.put(matches.group(1), sublist);
    } else {
       match.put(matches.group(1), matches.group(2));
    }
    list.add(match);
}
return list;

Я создал это регулярное выражение: \{(\w+)\}(.*)(?:\{\1\})? (obv не отформатирован здесь Java), но он не останавливаетсяна закрывающей фигурной скобке {/group1} вместо этого он просто продолжает захватывать все.

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

Вот Regex 101 , показывающий мои проблемы

1 Ответ

3 голосов
/ 20 марта 2019

Вы не за горами, вы можете использовать это регулярное выражение:

(?s)\{(\w+)}(.*?)\{/\1}

Обновленная демонстрация RegEx

В Java используйте:

final String regex = "(?s)\\{(\\w+)\\}(.*?)\\{/\\1\\}";

Подробности RegEx:

  • (?s): конец DOTALL mode
  • \{(\w+)}: Match opening tag as {tag} `и имя тега захвата в группе захвата #1
  • (.*?): сопоставить еще 0 символов (без жадности) и захватить его в группе # 2
  • \{/\1}: сопоставить закрывающий тег как {/tag}, используя обратную ссылкугруппа № 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...