java解析具有可变数量字段的字符串

时间:2013-07-10 14:00:56

标签: java parsing

我知道在Java中有很多关于解析的问题。 但是我无法弄清楚如何准确地解析以下字符串 -

输入字符串为 -

[[0, 0] -> 0, [0, 1] -> 1, [0, 2] -> 2, [1, 0] -> 3, [0, 4] -> 1, [0, 1] -> 2, [0, 6] -> 3, else -> 2

我希望将输出解析为 -

Entry 1 : number1, number2, number3
Entry 2 : number4, number5, number6
...

所以对于这个例子,输出将是 -

Entry 1 : 0, 0, 0
Entry 2 : 0, 1, 1
....

准确地说,else -> 2部分应该被忽略。

现在我的问题是 -

  • 一个条目包含的内容不是模式
  • 方括号之间的数字量可能会有所不同。 例如,输入字符串可以是 - [[0] -> 0, [1] -> 1, [2] -> 2, else -> 2

我尝试使用split来表示我展示的第二个例子 -

String value = "[[0] -> 0, [1] -> 1, [2] -> 2, else -> 2";
value = value.replaceAll("\\[", "");
value = value.replaceAll("\\]", "");
String split[] = value.split(",");

for(int j=0;j<split.length;j++)
{
    String split2[] = split[j].split("->");
    split2[0] = split2[0].replaceAll("\\s","");
    if(split2[0].contains("else"))
        continue;    
    System.out.println(split2[0],+ " " + split split2[1].replaceAll("\\s",""));                     
}

但这不适用于方括号中可变数量的数字。 我究竟应该如何进行模式匹配?我可以使用正则表达式吗?

谢谢!

2 个答案:

答案 0 :(得分:2)

您可以搜索下一个->,然后在下一个,之后进行拆分,以获得一个“细分”。现在,将该段拆分为->以获取“键”和“值”部分。最后,在剩余的,处拆分密钥以分隔密钥(如果它不是最终的“else”分段)。

String value = "[[0, 0] -> 0, [0, 1] -> 1, [0, 2] -> 2, [1, 0] -> 3, [0, 4] -> 1, [0, 1] -> 2, [0, 6] -> 3, else -> 2";
value = value.replaceAll("\\[", "");
value = value.replaceAll("\\]", "");
value = value.replaceAll(" ", "");               // remove spaces, too,
                                                 // no need to trim later
int start = 0;
while (start < value.length()) {
    int arrow = value.indexOf("->", start);      // next -> after start
    int comma = value.indexOf(",", arrow);       // next comma after ->
    comma = comma > -1 ? comma : value.length(); // final segment?

    String segment = value.substring(start, comma);
    String key = segment.split("->")[0];         // before ->
    String val = segment.split("->")[1];         // after ->

    if (key.contains("else")) {
        System.out.println("Default: " + val);
    } else {
        String[] keys = key.split(",");
        System.out.println(Arrays.toString(keys) + ": " + val);
    }
    start = comma + 1;                           // continue after segment
}

(输出与您更新的问题不完全匹配,但这应该很容易修复。)


您也可以使用像\[\d+(, \d+)*\] -> \d+这样的模式使用正则表达式。这与else部分不符,但我知道这无论如何都不重要。

String regex = "(\\[\\d+(, \\d+)*\\] -> \\d+)";
Matcher matcher = Pattern.compile(regex).matcher(value);
while (matcher.find()) {
    System.out.println(matcher.group());
}

matcher.group()的输出将是"[0, 0] -> 0"等字符串。

答案 1 :(得分:0)

支付输入格式的注意事项;寻找模式。括号数字范围的开头以'['开头。在范围是箭头“ - &gt;”,数字和逗号之后,括号内的数字范围的末尾以“]”结尾。看看下面代码的输出,你的解决方案应该很容易实现:

 public static void main(String[] args)
    {
        final String input = "[[3] -> 7, [0, 0] -> 0, [0, 1] -> 1, [0, 2] -> 2, [1, 0] -> 3, [0, 4] -> 1, [0, 1] -> 2, [0, 6] -> 3, else -> 2";
        String[] split;

        split = StringUtils.split(input, "->, ");

        for (String item : split)
        {
            System.out.println("Item: " + item);
        }
    }

注意:StringUtils是apache commons lang.

的一部分