首页 > 解决方案 > 正则表达式难以过滤结果

问题描述

所以,我在一个有半千台服务器的环境中。我每天都会收到每一个的备份警报。很难看出哪些需要注意。我有这个解析我的前景并使用正则表达式来查找匹配项的 powershell 脚本。每当出现问题时,我都会得到以下信息:

ServerA 错误 1:04:34 AM 1:00:12 AM (+1) 0.0 B 0.0 B 0.0 B (1x) 0:00:00 在复制间隔期间未处理增量复制

所以,我看到“错误”前面是服务器名称。

现在,我有:

(?m)^(?<servername>.+?)Error

它在错误之前抓住了项目,这很棒。但是,警报电子邮件还包含

由 bizznizz/nocgoblin 创建于 2019 年 4 月 30 日上午 10:46。错误

在最顶端,我不想要。

更糟糕的是,一些输入也是:

2019SRV-DB 90.2.0.10 错误 Microsoft Windows Server 2012 R2 标准

服务器名称由 IP 地址分隔。

我只需要抓取 2 到 15 个字符之间的 AZ、数字和连字符字符,以及不包含空格且不包含“。”的字符串。

我认为这应该做我想要的。

现在我有三个部分

主要表达:

(?m)^(?<servername>.+?)Error

应该过滤空格的逻辑

/^[^ ][\w\W ]*[^ ]/

以及应该过滤我想要的字符的逻辑

 /^[a-z][A-Z][0-9][-][^.]{2,15}$/

我只是不确定如何将它们放在一起。

这是我的测试输入的交互式示例:https ://regex101.com/r/hneDFw/3

有人可以告诉我如何做到这一点,或者为我提供一些好的材料来弄清楚这是怎么做到的吗?我是一个正则表达式菜鸟。

编辑:

这个问题已经得到解答,但是如果有人想查看我编写的用于解析我的 Outlook 以获取警报电子邮件的 powershell 脚本,那就去吧。

Add-Type -Assembly "Microsoft.Office.Interop.Outlook"
$Outlook = New-Object -ComObject Outlook.Application
$namespace = $Outlook.GetNameSpace("MAPI")

#------------
# Selects my Inbox, and then selects sub-folder under inbox. For my outlook, I have a subfolder called
# "Veeam Alerts" that I have an outlook rule put all of the account locked out alerts in
#------------
$inbox = $namespace.GetDefaultFolder([Microsoft.Office.Interop.Outlook.OlDefaultFolders]::olFolderInbox)    
$subfolder = $inbox.Folders('Veeam Alerts')

#------------
#I'm using RegEx here because selecting the values is super dooper easy. 
#------------
$RE = [RegEx]'(?m)^(?<servername>\S*)(?:\s+\d{1,3}(?:\.\d{1,3}){3})?\s+Error'

#------------
# For every email in my sub folder...
# (p.s., to check every email in "inbox", just replace $subfolder with $inbox)
#------------
$Data = ForEach ($item in $subfolder.items){

    #------------
    # Check to see if there's a match and if the recieved time is greater than the specified date, and if there is....
    #------------
    if ( ($item.body -match $RE) -and ($item.ReceivedTime -gt "7/01/2019" ) ) {
        #------------
        # Add it to $Data under "report"
        #------------
        Write-Host "Found: " $Matches.servername
        [PSCustomObject]@{
                report = $Matches.servername
        }
    }

}

#------------
# Now we sort through the data, count the occurence of each server, and export it to CSV.
#------------
$Data | Group-Object -Property report -NoElement | Sort-Object count | Export-CSv '.\backupfailed.csv' -NoTypeInformation

$confirmation = Read-Host "Report completed. File saved. When done reviewing data, type 'X' to close window"
if ($confirmation -eq 'x') {
    # proceed
}

标签: regex

解决方案


您可以使用

(?m)^(?<servername>\S*)(?:\s+\d{1,3}(?:\.\d{1,3}){3})?\s+Error

请参阅正则表达式演示

基本上,正则表达式匹配行开头的任何 0+ 非空白字符,以servername组捕获它们,然后使用可选的 IP 地址(如子字符串)并匹配一个Error单词。

细节

  • (?m)^- 一行的开始
  • (?<servername>\S*)- 组“服务器名”:0 个或多个非空白字符
  • (?:\s+\d{1,3}(?:\.\d{1,3}){3})?- 一个可选的非捕获组,匹配 1+ 个空格、1 到 3 位数字,然后出现三个点,后跟 1 到 3 位数字
  • \s+- 1+ 空格
  • Error- 一个Error子串。

推荐阅读