Сопоставление всего между двумя конкретными словами с использованием регулярных выражений - PullRequest
2 голосов
/ 27 августа 2010

Я пытаюсь проанализировать файл трассировки Oracle с помощью регулярных выражений. Мой язык выбора - C #, но я решил использовать Ruby для этого упражнения, чтобы познакомиться с ним.

Файл журнала несколько предсказуем. Большинство строк (99,8%, если быть точным) соответствуют следующей схеме:

# [Timestamp]                  [Thread]  [Event]   [Message]
# TIME:2010/08/25-12:00:01:945 TID: a2c  (VERSION) Managed Assembly version: 2.102.2.20
# TIME:2010/08/25-14:00:02:398 TID:1a60  OpsSqlPrepare2(): SELECT * FROM MyTable
line_regex = /^TIME:(\S+)\s+TID:\s*(\S+)\s+(\S+)\s+(.*)$/

Однако в некоторых местах журнала есть много сложных запросов, которые по некоторым причинам охватывают несколько строк:

Screenshot

Две вещи, на которые следует обратить внимание в этих записях, это то, что они, по-видимому, приводят к некоторому повреждению в файле журнала, потому что они заканчиваются непечатными символами, а затем внезапно следующая запись начинается в той же строке.

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

Есть ли более эффективный подход? Файл журнала, который мне нужно проанализировать, будет более 1,5 ГБ. Мое намерение состоит в том, чтобы нормализовать строки и удалить ненужные строки, чтобы в конечном итоге вставить их в виде строк в базу данных для запросов.

Спасибо!

Ответы [ 2 ]

2 голосов
/ 27 августа 2010

Регулярное выражение для сопоставления потенциально многострочных данных между строками «TIME:» и «TIME:» или концом файла:

/^TIME:(.+?)(?=TIME:|\z)/im

С другой стороны, как упоминает Джеймс, токенизация дляПодстроки «TIME:» или поиск позиций подстроки в «\ r \ nTIME:» (после первой записи «TIME:», в зависимости от формата разрыва строки) может оказаться лучшим подходом.

1 голос
/ 27 августа 2010

Может быть, лучше сделать это в старой школе, то есть читать ваш файл по одной строке за раз ... начинать с первого «ВРЕМЕНИ» и объединять свои строки до тех пор, пока не дойдет до следующего «ВРЕМЕНИ» ... Вы можете использовать регулярные выражения, чтобы отфильтровать любые ненужные строки.

Я не могу говорить с Руби; в C # это, конечно, StreamReader, что поможет вам разобраться с размером файла.

...