Разбиение строки в Java - PullRequest
       20

Разбиение строки в Java

1 голос
/ 23 декабря 2009

У меня есть несколько строк в следующем формате:
18.12.2009 02:08:26 Поступил Доу, Джон (карточка № 111) в южном лобби [В]

Из этих строк мне нужно вывести дату, время, имя и фамилию человека, а также номер карты. Допустимое слово может быть опущено, и все, что следует за последней цифрой номера карты, можно игнорировать.
У меня есть чувство, что я хочу использовать StringTokenizer для этого, но я не уверен.
Есть предложения?

Ответы [ 6 ]

3 голосов
/ 23 декабря 2009

String Tokenizer хорош, когда у вас есть общий разделитель, но в этом случае я бы выбрал регулярные выражения.

2 голосов
/ 23 декабря 2009

Ваш формат записи достаточно прост, чтобы я использовал метод String split , чтобы получить дату и время. Как отмечено в комментариях, наличие имен, которые могут содержать пробелы, усложняет ситуацию настолько, что разделение записи по пробелам не будет работать для каждого поля. Я использовал регулярное выражение, чтобы получить остальные три части информации.

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
2 голосов
/ 23 декабря 2009

Я бы пошел на java.util.Scanner ... этот код поможет вам начать ... вам действительно следует использовать шаблонную форму методов сканера, а не форму 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);
    }
}
1 голос
/ 23 декабря 2009

Несколько вещей, которые следует иметь в виду при разборе этой строки:

  • Фамилии могут содержать пробелы, поэтому вы должны искать ,
  • Имя может содержать пробел, поэтому ищите (

В связи с этим я отработал бы над ответом TofuBeer и настроил следующий для имени и фамилии. Разделение строк будет грязным из-за лишних пробелов.

0 голосов
/ 30 декабря 2009

Самое короткое решение регулярного выражения (с приведением типа):

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));
0 голосов
/ 23 декабря 2009

Доверяй своим мужествам ... :) С StringTokenizer:

import java.io.*;
import java.util.StringTokenizer;
public class Test {
  public Test() {
  }</p>

<p>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);
  }</p>

<p>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);
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...