Как я могу разобрать это без регулярных выражений? - PullRequest
1 голос
/ 15 апреля 2011

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

Вот как это выглядит:

 2 AB 123A 01JAN M ABCDEF AA1   100A  200A  02JAN T /ABCD /E    

Вот пример этого:

  • 2 - номер строки, они варьируются от 1 до 99.Если вы не видите из-за форматирования, есть префикс пробела с числами меньше 10.

    Пробел можно заменить или не заменить на *

  • AB - важная единица данных (UOD).

    AB может предшествовать /CD, что является еще одним важным UOD.

  • 123 является важным UOD.Он может варьироваться от 1 (с добавлением 4 пробелов) до 99999.

  • A является важным UOD.

  • 01JAN - это комбинация день / месяц, мне нужно извлечь оба UOD.

  • M - это краткая форма названия дня.Это может быть число от 1 до 7.

  • ABC является важным UOD.

  • DEF являетсяважный UOD.

    Пробел после DEF может быть *

  • AA1 может быть нулевым символом или может быть 5. Этоневажно.

  • 100A является отметкой времени, но может иметь формат 1300.A может быть N, когда время составляет 1200 или P для времени в PM.

  • Затем мы видим другую метку времени.

  • Следующая часть даты может отсутствовать, например, это действительно:

    93*DE/QQ51234 30APR J QWERTY*QQ0   1250   0520 /ABCD*ASDFAS /E             
    
  • Данные, где появляется /ABCD*ASDFAS /E, не имеют отношения к приложению,но здесь может появиться вторая отметка даты.Передняя косая черта может быть чем-то другим (например, буквой).

Примечание:
Это не ограничено пробелом, некоторые части тела работаютв другие.Положение символов является точным только для первых двух или трех элементов в списке

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

Ответы [ 4 ]

6 голосов
/ 16 апреля 2011

Это идеальное задание для регулярных выражений.Текст не содержит вложенности, и элементы, которые вы сопоставляете, довольно просто взяты по отдельности.

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

$regex = '@
    # 2 is the line number, these range from 1 all the way to 99.
    # There is a space character prepending numbers less than 10.
    # The space may or may not be replaced by an *.
    [ *]\d|\d\d
    \s

    # AB is an important unit of data (UOD).
    # AB may be prepended by /CD which is another important UOD.
    (/CD)?AB
    \s

    # 123 is an important UOD. It can range from 1 (prepended by 4 spaces)
    # to 99999.
    \s{4}\d{1}|\s{3}\d{2}|\s{2}\d{3}|\s{1}\d{4}|\d{5}
@x';

и т. Д.

2 голосов
/ 16 апреля 2011

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

1 голос
/ 16 апреля 2011

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

0 голосов
/ 16 апреля 2011

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

line_number = int(line_text[0:1])
ab_unit = line_text[3:4]
...

Если он действительно разделен пробелами, просто split() каждую строку, а затем анализируйте каждую, разбивая каждый фрагмент на составные части, где это необходимо.

...