Как извлечь поля из текстовой строки, которая не имеет постоянного разделителя? - PullRequest
1 голос
/ 04 марта 2010

Каков наилучший способ извлечь каждое поле из каждой строки, если между каждым полем нет четкого разделителя (разделителя)?

Вот пример строк, которые мне нужны для извлечения его полей:

3/3/2010 11:00:46 AM                      BASEMENT-IN          
3/3/2010 11:04:04 AM 2, YaserAlNaqeb      BASEMENT-OUT         
3/3/2010 11:04:06 AM                      BASEMENT-IN          
3/3/2010 11:04:18 AM                      BASEMENT-IN          
3/3/2010 11:14:32 AM 4, Dhileep              BASEMENT-OUT         
3/3/2010 11:14:34 AM                      BASEMENT-IN          
3/3/2010 11:14:41 AM                      BASEMENT-IN          
3/3/2010 11:15:33 AM 4, Dhileep           BASEMENT-IN          
3/3/2010 11:15:42 AM                      BASEMENT-IN          
3/3/2010 11:15:42 AM                      BASEMENT-IN          
3/3/2010 11:30:22 AM 34, KumarRaju        BASEMENT-IN          
3/3/2010 11:31:28 AM 39, Eldrin           BASEMENT-OUT         
3/3/2010 11:31:31 AM                      BASEMENT-IN          
3/3/2010 11:31:39 AM                      BASEMENT-IN          
3/3/2010 11:32:38 AM 39, Eldrin           BASEMENT-IN          
3/3/2010 11:32:47 AM                      BASEMENT-IN          
3/3/2010 11:32:47 AM                      BASEMENT-IN          
3/3/2010 11:33:26 AM 34, KumarRaju        BASEMENT-OUT         
3/3/2010 11:33:28 AM                      BASEMENT-IN    

В каждой строке 6 полей, некоторые из которых могут быть пустыми. Как лучше всего подойти к этой проблеме?

  • Я использую Java

Издание 01

  • Поле 5 может быть пустым (однако его существование должно быть распознано во всех случаях)
  • Количество мест может меняться
  • Последнее слово может измениться

Ответы [ 6 ]

2 голосов
/ 04 марта 2010

Ну, вы можете убрать дату и данные BASEMENT-FOO по номеру столбца, поскольку они всегда появляются в одной и той же точке линии. Затем вы можете разделить остаток на основе запятых. Нужно ли обрабатывать экранированные запятые \ или запятые в кавычках "foo, bar" - решать вам и вашим бизнес-требованиям.

1 голос
/ 04 марта 2010

Мне кажется, есть 3 метаполя:

3/3/2010 11:32:38 AM 39, Eldrin           BASEMENT-IN          
3/3/2010 11:32:47 AM                      BASEMENT-IN 

MF1: 3/3/2010 11:32:38 AM

MF2: 39, Eldrin

MF3: BASEMENT-IN

из которых MF2 является необязательным. Мои разделители тогда будут:

MF1 до [AM | PM] включительно

номер MF2, все, кроме ПОДВАЛА - *

MF3 ПОДВАЛ - *

Я не настолько хорош в регулярных выражениях, но я бы выделил эти 3 группы как что-то вроде

(anything)(AM|PM)(number,anything)?(BASEMENT-anything)

где? означает необязательную группу.

1 голос
/ 04 марта 2010

Вы можете сделать:

  • читать всю строку как строку.
  • разбить строку чтения на пробелы (\ s +). Вы должны получить 5 или 6 штук.
  • piece0, piece1 и piece2 будут дата, время и AM / PM.
  • проверить, есть ли номер 3: если да затем прочитайте следующий кусок как имя
  • последняя часть - это та вещь в подвале.
  • преобразовать кусочки из строки, чтобы сказать дата, время, int при необходимости.
0 голосов
/ 04 марта 2010

Поскольку каждое поле очень отличается (по крайней мере, в приведенном выше примере), вы можете сделать это:

  1. Разделить строку на токены.
  2. Запустите каждый элемент массива токенов через шаблон регулярных выражений.
0 голосов
/ 04 марта 2010

Найдите столбцы в каждой строке, где пустые символы соседствуют с непустыми, а затем выполните статистический анализ этих чисел: вполне вероятно, что границы полей встречаются в каждой строке или почти в каждой строке.

Аналогично для пунктуации рядом с буквами, но в целом невозможно угадать, предназначено ли - или a, для разграничения поля или нет. Если он встречается в одной и той же позиции в каждой строке, он может быть разделителем, но в списках вещей, таких как D-FL R-TX D-NY, это, вероятно, не так. Поэтому не может быть полностью автоматического решения для произвольных данных.

0 голосов
/ 04 марта 2010

Вы можете использовать Strtokenizer из Commons Lang и указать несколько разделителей для разделения на:

Существует ряд встроенных типов, которые поддерживаются через StrMatcher .

StrTokenizer(char[] input, StrMatcher delim) 

например.

StrMatcher delims = StrMatcher.charSetMatcher(new char[] {' ', ',', '\n'});
StrTokenizer str = new StrTokenizer(match.toString(), delims);
while (str.hasNext()) {
    System.out.println("Token:[" + str.nextToken() + "]");
}

даст (из примера выше):

Token:[3/3/2010]
Token:[11:00:46]
Token:[AM]
Token:[BASEMENT-IN]
Token:[3/3/2010]
Token:[11:04:04]
Token:[AM]
Token:[2]
Token:[YaserAlNaqeb]
Token:[BASEMENT-OUT]
Token:[3/3/2010]
Token:[11:04:06]
Token:[AM]
Token:[BASEMENT-IN]
Token:[3/3/2010]
Token:[11:04:18]
Token:[AM]
Token:[BASEMENT-IN]
Token:[3/3/2010]
Token:[11:14:32]
Token:[AM]
Token:[4]
Token:[Dhileep]
Token:[BASEMENT-OUT]
Token:[3/3/2010]
Token:[11:14:34]
Token:[AM]
Token:[BASEMENT-IN]
Token:[3/3/2010]
Token:[11:14:41]
Token:[AM]
Token:[BASEMENT-IN]
Token:[3/3/2010]
Token:[11:15:33]
Token:[AM]
Token:[4]
Token:[Dhileep]
Token:[BASEMENT-IN]
Token:[3/3/2010]
Token:[11:15:42]
Token:[AM]
Token:[BASEMENT-IN]
Token:[3/3/2010]
Token:[11:15:42]
Token:[AM]
Token:[BASEMENT-IN]
Token:[3/3/2010]
Token:[11:30:22]
Token:[AM]
Token:[34]
Token:[KumarRaju]
Token:[BASEMENT-IN]
Token:[3/3/2010]
Token:[11:31:28]
Token:[AM]
Token:[39]
Token:[Eldrin]
Token:[BASEMENT-OUT]
Token:[3/3/2010]
Token:[11:31:31]
Token:[AM]
Token:[BASEMENT-IN]
Token:[3/3/2010]
Token:[11:31:39]
Token:[AM]
Token:[BASEMENT-IN]
Token:[3/3/2010]
Token:[11:32:38]
Token:[AM]
Token:[39]
Token:[Eldrin]
Token:[BASEMENT-IN]
Token:[3/3/2010]
Token:[11:32:47]
Token:[AM]
Token:[BASEMENT-IN]
Token:[3/3/2010]
Token:[11:32:47]
Token:[AM]
Token:[BASEMENT-IN]
Token:[3/3/2010]
Token:[11:33:26]
Token:[AM]
Token:[34]
Token:[KumarRaju]
Token:[BASEMENT-OUT]
Token:[3/3/2010]
Token:[11:33:28]
Token:[AM]
Token:[BASEMENT-IN]
...