簡體   English   中英

PERL REGEX:單個字符串中包含多個排除/模式

[英]PERL REGEX: Multiple exclusion/patterns in a single string

對於某些黑暗而神秘的問題,我的正則表達式並沒有達到我的期望。

例:

示例文本要清理:

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

我只需要獲取用戶名

我的代碼是:

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

(PROTOCOL|APP)我的意思是定義不同的可能模式

\\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";

除非使用/x修飾符,否則正則表達式中的空格和制表符必須與目標字符串匹配。 在你的模式

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

您需要在逗號后面加一個空格,后跟一個空格字符。 \\s字符類與ASCII控制字符HTLFVTFFCR以及空格字符匹配。)同樣,在第二個冒號之后,您需要一個空格,后跟一個空格字符,然后是另一個空格匹配的模式。 在這兩種情況下,目標字符串中只有一個空格,因此模式將不匹配。 您還要求在最后一個封閉的方括號后加上一個空格,后跟一個空格字符,但您的數據似乎在該括號后結束。 您是否要匹配終止的換行符?

這會工作

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

但雙引號" ,逗號,和冒號:不需要逃避,這是最好使用/x修改任何東西,但瑣碎的模式,這樣就可以添加不重要的空白,揭示它們的結構也最好使用。如果您不需要捕獲字符串的那部分,則在PROTOCOLAPP周圍使用非捕獲括號(?: ... )

看一下這個程序,它似乎可以按照您的要求進行。

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

解決方案可能並不優雅,但可以滿足我的目的:

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;

如果我使用的是補丁解決方案,請通知我。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM