【问题标题】:Processing tuples in java在java中处理元组
【发布时间】:2014-09-17 08:26:48
【问题描述】:

我正在处理一些格式如下的数据:

String s = "{(30,2884090,1410450570357,235),(30,2863348,1410451100148,285)}"

有些疑惑困扰着我:

这个字符串中有两个条目(元组)吗?

我可以使用任何现成的数据结构来解析它吗?

有没有办法找出一个模式匹配,它可以为给定的 String 返回两个 Strings 的列表?

【问题讨论】:

  • 你试过用正则表达式匹配/分割吗?
  • @vikingsteve:我现在正在尝试。我希望避免的一个是拆分字符串 (s.split("),(") ,然后删除尾随和前导混乱..但我试图找出看起来更干净的正则表达式模式
  • @Fraz 刚刚\([,\d]*\) 怎么样,然后你在, 上分手,你就完了?或者您将整个(30,2884090,1410450570357,235) 作为一个条目,无论您需要什么。
  • 这可能有点矫枉过正,但如果您将(){} 替换为[],您的字符串将看起来像一个Json 列表列表。

标签: java string tuples


【解决方案1】:

据我所知,Java API 没有可以开箱即用的东西。您需要为此编写一个小型解析器。

为这样的事情编写解析器是微不足道的。这是一个好的开始:

public class TupleParser {

    /**
     * Not in use at the moment.
     */
    class TupleParserException extends RuntimeException {
        public TupleParserException(String arg) {
            super(arg);
        }
    }

    /**
     * Simple, recursive parser function.
     * 
     * @param input A String which contains all the tuples.
     * @param start Position where we start parsing.
     * @param output Where to store the result tuple.
     * @return An index of the character where we stopped parsing. 
     */
    public int parse(String input, int start, ArrayList output) {
        int idx = start;
        boolean finished = false;

        String part = "";

        while (idx < input.length() && !finished) {
            char ch = input.charAt(idx);
            switch (ch) {
                case '{':
                case '(':
                case '[':
                    ArrayList newTuple = new ArrayList();
                    output.add(newTuple);
                    ++idx;
                    idx = parse(input, idx, newTuple);
                    break;

                case '}':
                case ')':
                case ']':
                    output.add(part);
                    finished = true;
                    break;

                case ',':
                    output.add(part);
                    part = "";
                    break;

                default:
                    part += ch;
            } // switch
            ++idx;
        } // while

        return idx;
    }

    public ArrayList parse(String input) {
        ArrayList ret = new ArrayList();
        parse(input, 0, ret);
        return ret;
    }

    public static void main(String[] args) {
        String s = "{(30,2884090,1410450570357,235),(30,2863348,1410451100148,285)}";

        TupleParser tp = new TupleParser();
        ArrayList tuple = null;
        try {
            tuple = tp.parse(s);
            System.out.println(tuple.toString());
            tuple = tp.parse("1, 2, 5, 4"); // does not work yet
            System.out.println(tuple.toString());
        } catch (Exception e) {
            System.out.println(e.toString());
            e.printStackTrace();
        }
    }    
}

输出:

[[[30, 2884090, 1410450570357, 235], [30, 2863348, 1410451100148, 285]]]
[1,  2,  5]

【讨论】:

    【解决方案2】:

    可能不是最干净的解决方案,但也许您可以使用 StringTokenizer。

    s = s.substring(2, s.length()-4);      // cleans up the brackets in the beginning and end
    StringTokenizer st = new StringTokenizer(s, "),(", false);
    
    while(st.hasMoreTokens())
    {
        String block = st.nextToken();
        String[] values = block.split(",");
    }
    

    【讨论】:

      【解决方案3】:

      另一种方法是使用Matcher 类:

      Matcher m = Pattern.compile("(\\d+,)*\\d+").matcher(s);
      while (m.find()) {
              System.out.println(m.group());
      }
      

      不过,我喜欢 Serge Ballesta 的 使用 Json 进行反序列化的想法。

      【讨论】:

        猜你喜欢
        • 2012-04-02
        • 1970-01-01
        • 2021-10-15
        • 2017-09-20
        • 1970-01-01
        • 1970-01-01
        • 2022-08-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多