我想捕获这样的文本:
{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}
然后像这样把它变成 HashMap 的 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显示我的问题
最佳答案
你离得不远了,你可以使用这个正则表达式:
(?s)\{(\w+)}(.*?)\{/\1}
在 Java 中使用:
final String regex = "(?s)\\{(\\w+)\\}(.*?)\\{/\\1\\}";
正则表达式详细信息:
(?s)
:结束DOTALL
模式\{(\w+)}:将开始标签匹配为
{tag}` 并在捕获组 #1 中捕获标签名称(.*?)
:再匹配 0 个字符(非贪婪)并将其捕获到第 2 组\{/\1}
:通过使用第 1 组的反向引用将结束标记匹配为{/tag}
关于Java – 正则表达式 – 匹配开始和结束 curl 标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55257291/