【问题标题】:Java - String splittingJava - 字符串拆分
【发布时间】:2020-12-30 08:41:49
【问题描述】:

我读了一个txt,其中的数据格式如下:姓名地址爱好

示例(鲍勃·史密斯 ABC 街头游泳)

并将其分配给String z

然后我使用z.split 使用“”作为分隔符(空格)分隔每个字段,但它将Bob Smith 分隔为两个不同的字符串,而它应该作为一个字段,与地址相同。有没有一种方法可以让我以我想要的特定格式获取它?

P.S 抱歉,如果我解释得含糊其辞,英语不是我的母语。

String z;
try {
    BufferedReader br = new BufferedReader(new FileReader("desc.txt"));
    z = br.readLine();
} catch(IOException io) { 
    io.printStackTrace();
}
String[] temp = z.split(" ");

【问题讨论】:

  • "有没有一种方法可以让我获得我想要的特定格式?" - 使用不同的分隔符。
  • 没有算法可以知道名字或地址是什么。正如图灵85所说,使用不同的分隔符,如“;”
  • 我知道这是一个选项,但可以说我无法编辑 txt 文件以使分隔字符不同,例如“,”(逗号)
  • 那么我会说你手头有一项具有挑战性的任务。我们在写信时用换行符分隔收件人地址的不同部分是有充分理由的。

标签: java string split


【解决方案1】:

如果nameaddress 部分的格式固定为由两部分组成,您可以加入它们:

String z = "";  // z must be initialized

// use try-with-resources to ensure the reader is closed properly
try (BufferedReader br = new BufferedReader(new FileReader("desc.txt"))) {
    z = br.readLine();
} catch(IOException io) { 
    io.printStackTrace();
}

String[] temp = z.split(" ");

String name = String.join(" ", temp[0], temp[1]);
String address = String.join(" ", temp[2], temp[3]);
String hobby = temp[4];

另一种选择是创建一个格式字符串作为正则表达式,并使用它来使用命名组(?<group_name>capturing text)解析输入行:

// use named groups to define parts of the line
Pattern format = Pattern.compile("(?<name>\\w+\\s\\w+)\\s(?<address>\\w+\\s\\w+)\\s(?<hobby>\\w+)");
Matcher match = format.matcher(z);
if (match.matches()) {
    String name = match.group("name");
    String address = match.group("address");
    String hobby = match.group("hobby");
    System.out.printf("Input line matched: name=%s address=%s hobby=%s%n", name, address, hobby);
} else {
    System.out.println("Input line not matching: " + z);
}

【讨论】:

    【解决方案2】:

    split() 方法主要适用于两件事:

    • 分隔符
    • 字符串对象
    • 有时也有limit

    无论您提供什么限制,split() 方法都会根据该限制完成工作。 它不知道左子字符串是否是名称,与右子字符串相同。

    看看这段代码 sn-p:

    String assets = "Gold:Stocks:Fixed Income:Commodity:Interest Rates";
    String[] splits = assets.split(":");
    
    System.out.println("splits.size: " + splits.length);
    
    for(String asset: splits){
      System.out.println(assets);
    }
    
    OutPut
    
    splits.size: 5
    Gold
    Stocks
    Fixed Income         // with space
    Commodity
    Interest Rates       // with space
    

    输出带有 空格,因为我提供了 ; 作为分隔符。 这可能有助于您得到答案。

    查找关于 Split() 的详细信息:

    【讨论】:

      【解决方案3】:

      我能想到三个解决方案。

      从最好到最坏的顺序:

      1. 不同的分隔符
      2. 强制格式始终包含两个姓名、两个地址部分和一个爱好
      3. 有一本包含姓名和爱好的字典,检查每个单词以确定它是哪种类型,然后根据需要将它们组合在一起。

      (第 3 个选项并不是一个严肃的选择。)

      【讨论】:

        【解决方案4】:

        正如其他人所提到的,使用空格作为字段分隔符和内部字段是有问题的。您可以使用正则表达式模式来拆分行(将 (\w+ \w+) (\w+ \w+) (.+) 粘贴到 Regex101 中以获得解释):

        Pattern pattern = Pattern.compile("(\\w+ \\w+) (\\w+ \\w+) (.+)");
        Matcher matcher = pattern.matcher("Bob Smith ABC Street Bowling Fishing Rollerblading");
        
        System.out.println("matcher.matches() = " + matcher.matches());
        
        for (int i = 0; i <= matcher.groupCount(); i++) {
            System.out.println("matcher.group(" + i + ") = " + matcher.group(i));
        }
        

        这将给出以下输出:

        matcher.matches() = true
        matcher.group(0) = Bob Smith ABC Street Bowling Fishing Rollerblading
        matcher.group(1) = Bob Smith
        matcher.group(2) = ABC Street
        matcher.group(3) = Bowling Fishing Rollerblading
        

        但是,这只适用于这种确切的格式。例如,如果您得到包含三个名称部分的行:

        John B Smith ABC Street Swimming
        

        这将分为John B 作为名称,Smith ABC 作为地址,Street Swimming 作为爱好。

        因此,要么 100% 确保您的输入始终与此格式匹配,要么使用不同的分隔符。

        【讨论】:

          【解决方案5】:

          这取决于您处理的数据。名字是否总是由名字和姓氏组成?然后,您可以简单地将结果数组中的前两个元素组合成一个新字符串。

          否则,您可能必须找到一种不同的方法来分离 txt 文件中的不同部分。可能是逗号?您知道的某些字符永远不会在您的正常数据中使用。

          【讨论】:

            【解决方案6】:

            假设每一行都遵循格式

            鲍勃·史密斯 ABC 街头游泳

            即,姓氏....此代码可以为您手动操作数据:

                    String[] temp = z.split(" ");
                    String[] temp2 = new String[temp.length - 1];
                    temp2[0] = temp[0] + " " + temp[1];
                    for (int i = 2; i < temp.length; i++) {
                        temp2[i] = temp2[i];
                    }
                    temp = temp2;
            

            【讨论】:

              猜你喜欢
              • 2014-05-27
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多