Java解析嵌套的“标签”

时间:2015-07-16 07:12:05

标签: java regex parsing

我有“标签”,格式为

{id|attribute|context|comment|flag1|flag2|...}

问题是,id部分可以是嵌套标记,如下所示:

{{id|attribute|||flag}|attribute}

甚至

{{{{id|attribute}|attribute}|attribute}|attribute}

理论上,嵌套可以无限期地继续下去。我正在尝试找到一种解析可能包含任意数量字符串的文本的好方法,如此

{7953|title} is a {7953|generic} in {{7953|setting}|title}.
{5514|name} lives in {7953|title}.
{{{3216|carrier|20140205191631}|origin}|pronoun||deeply rooted|first|possessive} favorite ...

你明白了。我需要一种方法来查找给定文本块中的每个“标记”。有些事情要注意

  • 字段分隔符是|
  • 标签只需要前两个字段
    • 缺少的字段由连续的| s
    • 表示
  • 标签可以任意嵌套,但只能在第一个位置
  • 空格 IS 重要(它是字段的一部分,不应忽略)
  • 可以有任意数量的标志字段
  • 所有字段都可以包含任何字符(包括idcontext),因此{,}和|必须用\来逃避(例如\ |不会分隔字段)

我知道我可以通过横切字符串来解析它,并跟踪我何时触发标记开始,我有多深入嵌套,当我的深度达到0时,并抓住它们之间的所有内容,但这有点痛苦。< / p>

如果可能的话,我想用正则表达式来做,但Java不支持递归正则表达式。

解析此问题的最佳方法是什么?

额外信息

如果它有所不同,“标签”将被解析为一个对象(解析和构建的对象),然后可以将对象渲染到它所代表的字符串。这就是为什么正则表达式更好,因为我可以使用Matcher::appendReplacementMatcher::appendTail

1 个答案:

答案 0 :(得分:0)

这是我用来解析包含“tags”的文本的代码:

public static String parseText(String text) {
    StringBuilder oldText = new StringBuilder(text);
    StringBuilder newText = new StringBuilder();
    int firstTag = oldText.indexOf("{");
    FullBreak:
    while (firstTag >= 0) {
        newText.append(oldText.substring(0, firstTag));
        oldText.delete(0, firstTag);
        int depth = 1;
        int position = 0;
        while (depth > 0) {
            position++;
            if (position > oldText.length() - 1) {
                break FullBreak;
            }
            if (oldText.charAt(position) == '{' && oldText.charAt(position - 1) != '\\') {
                depth++;
            }
            if (oldText.charAt(position) == '}' && oldText.charAt(position - 1) != '\\') {
                depth--;
            }
        }
        position++;
        newText.append(parseTag(oldText.substring(0, position)).render());
        oldText.delete(0, position);
        firstTag = oldText.indexOf("{");
    }
    newText.append(oldText);
    return newText.toString();
}

在这种情况下,parstTag(String)会返回Tag,其中包含render()方法。