【问题标题】:stringtokenizer returns wrong tokensstringtokenizer 返回错误的标记
【发布时间】:2012-09-23 14:06:34
【问题描述】:

我想将给定的字符串“解析”成向量。向量以“[”开头,以“]”结尾。向量的值以及向量本身由“,”分隔。如果我使用整数作为值,我的代码可以正常工作“[1,2,3],[5,2,3],[1,6,3]”。但是当我将整数值与双精度值 "[1,2.5,3],[5,2,3],[1,6,3]" 混合时,stringtokenizer 返回错误的值(在这种情况下是“ 1" "2.5" 然后是 "3]" ......)

String s = "[1,2.5,3],[5,2,3],[1,6,3]";

Vector<Vector<Double>> matrix = new Vector<Vector<Double>>();        
for(int j=0;j<s.length();j++) {
   if (s.charAt(j)=='[') {
      int k=s.indexOf("]");      
      StringTokenizer st = new StringTokenizer(s.substring(j+1, j+k));// j+k-1 does not work either
      Vector<Double> vector = new Vector<Double>();
      while (st.hasMoreTokens()) {
          vector.add(Double.parseDouble(st.nextToken(",")));//Exception in thread     "main" java.lang.NumberFormatException: For input string: "3]"
      }
      matrix.add(vector);
   }
}

【问题讨论】:

    标签: java stringtokenizer


    【解决方案1】:
    if (s.charAt(j)=='[') {
        int k=s.indexOf("]"); 
    

    查找]s 中第一次出现的索引,从字符串的开头开始。你真正想要的是找到当前向量开始之后的第一个匹配项

    if (s.charAt(j)=='[') {
        int k = s.indexOf("]", j);
    

    当你只有2 而不是2.5 时它起作用的原因是每个向量中的字符数恰好相同,因此以] 的第一次出现来计算长度矢量靠运气工作。

    注意,您还必须将 substring 调用的结束索引更改为 k

    StringTokenizer st = new StringTokenizer(s.substring(j+1, k));
    

    附带说明,不建议使用StringTokenizer。在这种情况下,您应该改用split()

    String[] elements = s.substring(j+1, k).split(",");
    Vector<Double> vector = new Vector<Double>();
    for (String element : elements) {
        vector.add(Double.parseDouble(element));
    }
    matrix.add(vector);
    

    【讨论】:

    • 没错,我已经监督了!坦克 =)
    • int k=s.indexOf("]",j); // 需要添加 j StringTokenizer st = new StringTokenizer(s.substring(j+1, k)); //需要删除+j
    • 是的,我只是在更新我的答案,以便在您发布时说。 :)
    【解决方案2】:

    Vector 和 StringTokenizer ? :) 可爱!

        while(s.contains("[")) {
            String s1 = s.substring(s.indexOf("[")+1, s.indexOf("]"));
            if(s1!=null && s1.isEmpty()!=true && s1.contains(",") ) {
                String[] sArr = s1.split(",");
                for (String string : sArr) {
                    Double d = Double.valueOf(string);
                    System.out.println(d);
                    // put it where you need
                }
            }
            s = s.substring(s.indexOf("]")+1);
        }
    

    【讨论】:

    • 我应该使用 split 而不是 stringtokenizer 只是因为它更快还是有其他原因?这不像我必须“解析” 100k 字符长字符串。
    • 如果您查看 String.split() 并将其与 StringTokenizer 进行比较,相关区别在于 String.split() 使用正则表达式,而 StringTokenizer 仅使用逐字拆分字符。因此,如果我想用比单个字符更复杂的逻辑来标记一个字符串(例如,在 \r\n 上拆分),我不能使用 StringTokenizer 但我可以使用 String.split()
    【解决方案3】:

    StringTokenizer 已弃用,您应该使用字符串split()

    【讨论】:

    • 首先,StringTokenizer 已被弃用,但是 "建议任何寻求此功能的人使用 String 的 split 方法或 java.util .regex 包代替”。其次,这实际上并不能回答问题,应该是评论。
    猜你喜欢
    • 1970-01-01
    • 2011-02-12
    • 2014-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-11
    • 1970-01-01
    相关资源
    最近更新 更多