Regex, как вернуть две строки из файла журнала

У меня есть большой файл журнала, я пытаюсь извлечь две части информации из регулярного выражения powershell в одну строку. Лог содержит всевозможные данные, но интересующие меня блоки я привел в пример ниже. Я пытаюсь найти пользователей, которые входят в систему с неправильной версией приложения.

Пример данных (это не отображается в предварительном просмотре, но есть разрывы строк):

Device User Name: CDALLAS
Is SSO          : false
Versions        : id=VNF-Android
0=Client-Version,VN v4.82.1;android;SM-G900V,.

Device User Name: smith5
Is SSO          : false
Versions        : id=VNF-Android
0=Client-Version,VNNEXT v4.32,.

Device User Name: joe123
Is SSO          : false
Versions        : id=VNF-iOS
0=Client-Version,APPSTORE v5.89;iPhone OS;iPhone8   1,.

Что мне нужно вернуть для каждого из них:

CDALLAS 4.82.1

smith5 4.32

joe123 5.89

В идеале я бы хотел исключить любые записи с 4.82.1, так как это правильная версия.

Для части имени пользователя я могу использовать что-то вроде (?<=Device User Name: )(.*)

Но как мне получить рядом с ним номер версии?
Номеру версии всегда предшествует "Client-Version" (какой-то текст) "v" (номер версии), затем либо a , либо ;

Regex всегда вызывал у меня головную боль. Любая помощь будет принята с благодарностью.


person Steve J    schedule 02.06.2016    source источник


Ответы (2)


Эта regex работа должна работать на вас:

Device User Name:\s+\b(?<name>\w+).*?(?<=Client-Version).*?v(?<version>\d[^;,]+)

Визуализация регулярных выражений

Демонстрация регулярных выражений.

Чтобы использовать его в PowerShell, вы должны использовать опцию [System.Text.RegularExpressions.RegexOptions]::Singleline:

$content = Get-Content 'YOUR_FILE_PATH' -raw
$regex = 'Device User Name:\s+\b(?<name>\w+).*?(?<=Client-Version).*?v(?<version>\d[^;,]+)'
[regex]::Matches($content, $regex, [System.Text.RegularExpressions.RegexOptions]::Singleline) | ForEach-Object {
    '{0} {1}' -f $_.Groups['name'].Value, $_.Groups['version'].Value
}

Вывод:

CDALLAS 4.82.1
smith5 4.32
joe123 5.89
person Martin Brandl    schedule 02.06.2016

похоже, у вас уже есть решение, но вот кое-что, что тоже может быть полезно

$text = @'
Device User Name: CDALLAS
Is SSO          : false
Versions        : id=VNF-Android
0=Client-Version,VN v4.82.1;android;SM-G900V,.

Device User Name: smith5
Is SSO          : false
Versions        : id=VNF-Android
0=Client-Version,VNNEXT v4.32,.

Device User Name: joe123
Is SSO          : false
Versions        : id=VNF-iOS
0=Client-Version,APPSTORE v5.89;iPhone OS;iPhone8   1,.

'@.Split("`n")

$hash = @{}
$text | % {
    if ($_ -match ': ') {
        $split = $_.Split(':').Trim()
        $hash.Add($split[0], $split[1])
    } elseif ($_ -match ' v([0-9\.]+)') {
        $hash.Add('Version', $Matches[1])
        [pscustomobject]$hash
        $hash = @{}
    }
}

# yields:
# Is SSO Version Device User Name Versions      
# ------ ------- ---------------- --------      
# false  4.82.1  CDALLAS          id=VNF-Android
# false  4.32    smith5           id=VNF-Android
# false  5.89    joe123           id=VNF-iOS 
person Anthony Stringer    schedule 02.06.2016