【问题标题】:Breaking up a String in Java在 Java 中拆分字符串
【发布时间】:2009-12-23 05:47:45
【问题描述】:

我有多个格式如下的字符串:
2009 年 12 月 18 日 02:08:26 在南大堂录取 Doe, John(卡 #111)

从这些字符串中,我需要得到日期、时间、人的名字和姓氏以及卡号。可以省略“承认”一词,并且可以忽略卡号最后一位之后的任何内容。
我有一种感觉,我想为此使用 StringTokenizer,但我并不积极。
有什么建议吗?

【问题讨论】:

  • 如果这是您正在读取的文件,我会很想对其进行处理并将其保存在另一个文件中,例如 CSV 格式,这样更易​​于处理。这是因为字段相关信息可以包含空格。要么改变它的编码方式。

标签: java string


【解决方案1】:

当你有一个共同的分隔符时,字符串标记器很棒,但在这种情况下,我会选择正则表达式。

【讨论】:

  • 因此,作为从字符串中提取日期的示例,我正在尝试以下操作:Pattern datePattern = Pattern.compile("[0-9]{2}/[0-9] {2}/[0-9]{4}" );然后在字符串上使用 Matcher,使用该模式,我没有得到任何结果。我该如何正确格式化这个正则表达式?
【解决方案2】:

您的记录格式很简单,我只需使用 String 的 split 方法来获取日期和时间。正如 cmets 中所指出的,具有可以包含空格的名称会使事情复杂化,以至于用空格分割记录并不适用于每个字段。我使用正则表达式来获取其他三个信息。

public static void main(String[] args) {
    String record1 = "12/18/2009 02:08:26 Admitted Doe, John (Card #111) at South Lobby [In]";
    String record2 = "12/18/2009 02:08:26 Admitted Van Halen, Eddie (Card #222) at South Lobby [In]";
    String record3 = "12/18/2009 02:08:26 Admitted Thoreau, Henry David (Card #333) at South Lobby [In]";

    summary(record1);
    summary(record2);
    summary(record3);
}

public static void summary(String record) {
    String[] tokens = record.split(" ");

    String date = tokens[0];
    String time = tokens[1];

    String regEx = "Admitted (.*), (.*) \\(Card #(.*)\\)";
    Pattern pattern = Pattern.compile(regEx);
    Matcher matcher = pattern.matcher(record);
    matcher.find();

    String lastName = matcher.group(1);
    String firstName = matcher.group(2);
    String cardNumber = matcher.group(3);

    System.out.println("\nDate: " + date);
    System.out.println("Time: " + time);
    System.out.println("First Name: " + firstName);
    System.out.println("Last Name: " + lastName);
    System.out.println("Card Number: " + cardNumber);
}

正则表达式"Admitted (.*), (.*) \\(Card #(.*)\\)" 使用分组括号来存储您尝试提取的信息。必须对记录中存在的括号进行转义。

运行上面的代码会给我以下输出:

Date: 12/18/2009
Time: 02:08:26
First Name: John
Last Name: Doe
Card Number: 111

Date: 12/18/2009
Time: 02:08:26
First Name: Eddie
Last Name: Van Halen
Card Number: 222

Date: 12/18/2009
Time: 02:08:26
First Name: Henry David
Last Name: Thoreau
Card Number: 333

【讨论】:

  • 很好,但这会破坏带有空格的名称。例如“范海伦,埃迪”
  • @Adriaan:感谢您指出这一点。现实世界的数据有时是如此痛苦! :) 我更改了我的代码以使用正则表达式来提取那些受名称中的空格影响的数据。
  • 很好的答案。稍后可能会发布一个变体。
【解决方案3】:

我会选择 java.util.Scanner...此代码将帮助您入门...您应该真正使用扫描器方法的 Pattern 形式,而不是我使用的 String 形式。

import java.util.Scanner;

public class Main
{
    public static void main(String[] args)
        throws Exception
    {
        final String  str;
        final Scanner scanner;
        final String  date;
        final String  time;
        final String  word;
        final String  lastName;
        final String  firstName;

        str       = "12/18/2009 02:08:26 Admitted Doe, John (Card #111) at South Lobby [In]";
        scanner   = new Scanner(str);
        date      = scanner.next("\\d+/\\d+/\\d+");
        time      = scanner.next("\\d+:\\d+:\\d+");
        word      = scanner.next();
        lastName  = scanner.next();
        firstName = scanner.next();
        System.out.println("date : " + date);
        System.out.println("time : " + time);
        System.out.println("word : " + word);
        System.out.println("last : " + lastName);
        System.out.println("first: " + firstName);
    }
}

【讨论】:

    【解决方案4】:

    解析这一行时要记住的几点:

    • 姓氏可以有空格,因此您应该寻找,
    • 名字可以有空格,因此请查找 (

    因此,我会根据 TofuBeer 的回答来调整名字和姓氏的下一个。由于多余的空格,字符串拆分会很混乱。

    【讨论】:

      【解决方案5】:

      最短的正则表达式解决方案(使用类型转换):

      String stringToParse = "12/18/2009 02:08:26 Admitted Doe, John (Card #111) at South Lobby [In] ";
      Pattern pattern = Pattern.compile("((\\d{2}/){2}\\d{4}\\s(\\d{2}:){2}\\d{2})\\s(\\w+)\\s((.*)),\\s((.*))\\s.*#(\\d+)");
      Matcher matcher = pattern.matcher(stringToParse);
      matcher.find();
      
      String firstName = matcher.group(6);
      String lastName = matcher.group(5);
      int cardNumber = Integer.parseInt(matcher.group(7));
      
      DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
      Date date = df.parse(matcher.group(1));
      

      【讨论】:

        【解决方案6】:

        相信你的胆量... :) 使用 StringTokenizer:

        import java.io.*;
        import java.util.StringTokenizer;
        public class Test {
          public Test() {
          }
        
        

        public void execute(String str) { String date, time, firstName, lastName, cardNo; StringTokenizer st = new StringTokenizer(str, " "); date = st.nextToken(); time = st.nextToken(); st.nextToken(); //Admitted lastName = st.nextToken(",").trim(); firstName = st.nextToken(",(").trim(); st.nextToken("#"); //Card cardNo = st.nextToken(")#"); System.out.println("date = " + date +"\ntime = " + time +"\nfirstName = " + firstName +"\nlastName = "+ lastName +"\ncardNo = " +cardNo); }

        public static void main(String args[]) { Test t = new Test(); String record1 = "12/18/2009 02:08:26 Admitted Doe, John (Card #111) at South Lobby [In]"; String record2 = "12/18/2009 02:08:26 Admitted Van Halen, Eddie (Card #222) at South Lobby [In]"; String record3 = "12/18/2009 02:08:26 Admitted Thoreau, Henry David (Card #333) at South Lobby [In]"; t.execute(record1); t.execute(record2); t.execute(record3); } }

        【讨论】:

        • 谢谢,但是使用 StringTokenizer,我将如何分解字符串?
        猜你喜欢
        • 2015-03-30
        • 2012-03-21
        • 2013-02-07
        • 1970-01-01
        • 2014-05-27
        • 1970-01-01
        相关资源
        最近更新 更多