2015-02-01 2 views
0

Для какого-то темного и загадочного вопроса мой рег-экс не тянет то, что я ожидаю;PERL REGEX: Несколько исключений/шаблонов в одной строке

Пример:

примеры текста для очистки:

[PROTOCOL (Id:"hashguy82", ProcessID: 45)] 
[APP (Id:"hashguy83", ProcessID: 67)] 

Мне нужно только, чтобы получить имя пользователя

мой код:

\[(PROTOCOL|APP)\s\(Id:\"(\w+)\"\, \s ProcessID\: \s \d+\)] \s 

(PROTOCOL|APP) Я имела в виду определение разные возможный патте RNS

\s Я имел в виду пространства

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

Пример Строка:

2015-01-27 00:00:09,654 TRACE [APP (Id:"HashMap81", ProcessId: 62)] PerformanceLogger (PerformanceLogger.Python:29) - Client:344,UserId:13383,Ip:127.0.0.1,DurationMillis:272,DurationText:0.272 seconds,Path:MyClass.myMethod 

Полный код:

my $file = 'path_my_file.txt'; 
open my $fh, "<", $file or die "Could not open $file: $!"; 


while (<$fh>) { 
    my @fields = m{^ 
     (\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:[\d,]+) 
     \s (WARNING|TRACE) \s\s 
     qr/ \[ (?: APP| PROTOCOL) \s* \(Id:"(\w+)", \s* ProcessID: \s* \d+ \) \] /x \s 
     \s PerformanceLogger \s \(PerformanceLogger\.Python\:\d+\) \s - \s 
     Client:(\d+), 
     UserId:(\d+), 
     Ip:([\d.]+), 
     DurationMillis:\d+, 
     DurationText:([\d.]+) \s seconds, 
     Path:/(\S+) 
    $}x 
    or next; 

    printf('$date=%s; $level=%s; $user=%s; $client_id=%s; $user_id=%s; $ip=%s; $elapsedTime=%s; $classMethod=%s', @fields); 
    print "\n"; 
+1

Ваше регулярное выражение ищет строку 'User:', но нет такой строки i Ваши данные. – Borodin

+0

Приносим извинения за опечатку. Исправлено сейчас: Мне нужно принимать значения hasguy82 и hashguy83; давайте предположим, что мое описание у меня есть файл с двумя строками, которые мне нужно хранить, используя мое регулярное выражение, просто userid..eliminating все остальное; я чувствую, что «в PERL смущен чем-то другим ... Как вы думаете? – HashGuy81

+0

Потерять пробелы:' \ [(PROTOCOL | APP) \ s \ (Id: \ "(\ w +) \" \, \ sProcessID \: \ s \ d + \)] \ s' – pajaja

ответ

1

Если вы не используете /x модификаторов, пробелы и вкладки в своем регулярном выражении должны быть согласованы в целевой строке. В вашем шаблоне

\[(PROTOCOL|APP)\s\(Id:\"(\w+)\"\, \s ProcessID\: \s \d+\)] \s 

Требуется пробел, за которым следует пробельный символ после запятой. (Класс \s символов соответствует управляющим символам ASCII HT, LF, VT, FF и CR, а также символ пробела.) Точно так же, после второго двоеточия нужно пространство, за которым следует символ пробела, а затем другого пространство для шаблон для соответствия. В обоих случаях в целевой строке есть только одно пространство, поэтому шаблон не будет соответствовать. Вы также запрашиваете пробел, за которым следует символ пробела после заключительной квадратной скобки, но ваши данные, похоже, заканчиваются в скобке. Вы пытались сопоставить завершающую новую строку?

Это будет работать

\[(PROTOCOL|APP)\s\(Id:\"(\w+)\"\,\sProcessID\:\s\d+\)] 

но двойные кавычки ", запятые , и двоеточие : не нужно бежать, и это лучше всего использовать модификатор /x на что-либо, кроме тривиальных моделей, так что вы можете добавить незначительные пробелы, чтобы выявить их структуру. Также лучше использовать не захватывающие круглые скобки (?: ...) около PROTOCOL и APP, если вам не нужно захватывать эту часть строки.

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

use strict; 
use warnings; 

my $re = qr/ \[ (?: PROTOCOL | APP) \s* \(Id:"(\w+)", \s* ProcessID: \s* \d+ \) \] /x; 

while (<DATA>) { 
    print $1, "\n" if /$re/; 
} 

__DATA__ 
[PROTOCOL (Id:"hashguy82", ProcessID: 45)] 
[APP (Id:"hashguy83", ProcessID: 67)] 

выход

hashguy82 
hashguy83 
+0

Borodin Я добавил свой код и строку по умолчанию пример в основной части этого сообщения .... сводит меня с ума, он работал вчера ... :( – HashGuy81

+0

Ваши новые данные имеют «ProcessId», где ваши исходные данные имеют «ProcessID». Кроме того, ваш * Coomplete Code * имеет Perl regex 'qr/\ [(?: GUI | SOAP) \ s * \ (User:" (\ w +) ", \ s * ThreadId: \ s * \ d + \) \]/x' встроен в другое регулярное выражение – Borodin

+0

Нет причин использовать qr // в этом коде. – ikegami

0

решение, вероятно, не элегантно, но работает для моей цели:

while (<$fh>) { 
    my @fields = m{^ 
     (\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:[\d,]+) 
     \s (?: WARNING | TRACE) \s\s 
     \[(?: APP | PROTOCOL)\s[(]Id:["](\w+)",\sProcessID:\s\d+\)] 
     \s PerformanceLogger \s \(PerformanceLogger\.Python\:\d+\) \s - \s 
     Client:(\d+), 
     UserId:(\d+), 
     Ip:([\d.]+), 
     DurationMillis:\d+, 
     DurationText:([\d.]+) \s seconds, 
     Path:(\S+) 
    $}x 
    or next; 

Пожалуйста, если я использую раствор зашивки предупредите меня ....

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