2016-07-29 2 views
0

Я хочу повернуть некоторые данные по нескольким строкам в одну строку с регулярным выражением.Как перенести данные в Perl только с регулярным выражением?

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

(\d+-\d+-\d+) (\d+:\d+:\d+,\d+) INFO (\[com\.LoggingFilter\]) \(([^)]+)\) (\d+) \* Server in-bound request 
(?=\5 > (.+) 
[\s\S]* 
\5 > user-agent:\s*(.+) 
[\s\S]* 
(\d+-\d+-\d+) (\d+:\d+:\d+,\d+) INFO \3 \(\4\) \5 \* Server out-bound response 
\5 < (\d+) 
[\s\S]*) 

Это (почти) работает: VIEW regex in action. Некоторые детали (сохраненные положительным взглядом вперед) по-прежнему сохраняются после замены регулярных выражений. Как получить следующий результат

"88598";"2016-07-29";"00:00:08,262";"2016-07-29";"00:00:08,262";"http-10.2.3.4-8080-14";"Java/1.7.0_79";"303";"GET http://1.2.3.4:8080/service/api/ 
"88599";"2016-07-29";"00:00:08,382";"2016-07-29";"00:00:08,382";"http-10.2.3.4-8080-8";"Java/1.7.0_79";"303";"GET http://1.2.3.4:8080/service/api/" 
(...) 

вместо того

"88598";"2016-07-29";"00:00:08,262";"2016-07-29";"00:00:08,262";"http-10.2.3.4-8080-14";"Java/1.7.0_79";"303";"GET http://1.2.3.4:8080/service/api/"88598 > GET http://1.2.3.4:8080/service/api/ 
<garbage data here> 
"88599";"2016-07-29";"00:00:08,382";"2016-07-29";"00:00:08,382";"http-10.2.3.4-8080-8";"Java/1.7.0_79";"303";"GET http://1.2.3.4:8080/service/api/"88599 > GET http://1.2.3.4:8080/service/api/ 
(...) 
+0

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

+2

@DaveCross Это в демо-версии regex. – horcrux

+2

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

ответ

0

Это похоже на работу:

(\d+-\d+-\d+) (\d+:\d+:\d+,\d+) INFO (\[com\.LoggingFilter\]) \(([^)]+)\) (\d+) \* Server in-bound request 
(?=\5 > (.+) 
[\s\S]* 
\5 > user-agent:\s*(.+) 
[\s\S]* 
(\d+-\d+-\d+) (\d+:\d+:\d+,\d+) INFO \3 \(\4\) \5 \* Server out-bound response 
\5 < (\d+) 
[\s\S]*)[\s\S]*?((?=\n.*Server in-bound request)|(?![\s\S])) 

Here демо.

+0

Если в мусоре появляется 'Server in-bound request', он сохраняется в конечном результате. Смотрите: https://regex101.com/r/tS9aD7/2 – Stephan

+0

В некотором роде у вас должен быть критерий, чтобы отличить мусор от ненужных мусора. Если в мусоре может появиться '\ n. * Server in-bound request', замените его чем-то более маловероятным. Например, весь файл '\ n \ d + - \ d + - \ d + \ d +: \ d +: \ d +, \ d + INFO + \ [com \ .LoggingFilter \] \ ([^)] + \) \ d + \ * in-bound request'? См. [Здесь] (https://regex101.com/r/tS9aD7/3). – horcrux

+0

Вашему шаблону нужно много шагов, чтобы найти матч, и я подозреваю, что реальный файл будет больше, чем образец. Вследствие этого шаблона вы можете быстро достичь предела возврата. Даже если я считаю, что подход * только регулярного выражения * не подходит, я попытался улучшить шаблон, чтобы уменьшить количество шагов. Результат вы найдете здесь: https://regex101.com/r/lT4vV4/1 –

Смежные вопросы