У меня есть несколько строк, которые в следующем формате:
12/18/2009 02:08:26 Допускаются Doe, John (Card # 111) в Южной Lobby [В]
Из этой строки мне нужно выбрать дату, время, имя и фамилию человека и номер карты. Слово допустимое может быть опущено, и все, что следует за последней цифрой номера карты, можно игнорировать.
У меня такое чувство, что я хочу использовать StringTokenizer для этого, но я не уверен.
Любые предложения?Разбиение строки в Java
ответ
Ваш формат записи достаточно просто, что я бы просто использовать 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
Приятно, но это ломается для имен с пробелами в них. Например, «Van Halen, Eddie» –
@Adriaan: Спасибо, что указали это. Данные в реальном мире - такая боль иногда! :) Я изменил свой код, чтобы использовать регулярные выражения, чтобы вытащить те части данных, на которые повлияли пробелы в именах. –
Спасибо, Билл. Это сработало отлично. – clang1234
Доверяйте своим кишок ... :) С 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); } }
Строка Tokenizer является большим, когда у вас есть общий ограничитель, но в данном случае я выбрал бы для регулярных выражений.
+1 для регулярного выражения. – Ross
Как пример для вычеркивания даты из строки, я пытаюсь сделать следующее: Дата созданияPattern = Pattern.compile ("[0-9] {2}/[0-9] {2}/[0-9] {4}"); Затем, используя Matcher на строке, с этим шаблоном, я не получаю результата. Как правильно форматировать это регулярное выражение? – clang1234
Судебная и ошибка: http://www.regexplanet.com/simple/ –
Я бы пошел на 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);
}
}
Несколько вещей, чтобы иметь в виду, в то время как вы разбираем эту строку:
- Фамилии может иметь пробелы, так что вы должны быть ищу ,
- имя может иметь пространство так искать для (
В связи с этим я отработаю ответ от TofuBeer и настрою следующий для имени и фамилии. Разделение строк будет грязным из-за дополнительных пробелов.
Кратчайший регулярное_выражение решение (с литьем типа):
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));
Если это файл, который вы читаете из, я был бы соблазн обработать его и сохранить его во втором файле, скажем, в формате CSV, это легче обрабатывать. Это связано с тем, что полевая информация может содержать пробелы. Либо это, либо изменить способ его кодирования. –