当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] 使用 PowerShell 和正则表达式捕获名称

作者:精品下载站 日期:2024-12-14 07:55:22 浏览:16 分类:玩电脑

使用 PowerShell 和正则表达式捕获名称


当您继续学习和使用 PowerShell 时,您最终会遇到正则表达式。希望你们中的许多人已经具备一些基础知识。如果没有,首先要开始阅读帮助主题 about_regular_expressions 在本文中,我将向您介绍一个高级正则表达式主题 - 名为捕获。我承认,当我第一次学习这个话题时,它让我头晕目眩。但希望我能减慢旋转木马的速度。

让我们从这样的字符串开始。

$t = "2019-06-21 17:12:31Z : 172.16.1.123 [ Begin process data ]"

这可能是您日志文件中的内容。由于PowerShell的优势来自于它处理对象的能力,因此将日志文件转换为对象集合可能会更容易。

从模式开始

为了使其发挥作用,并且为了使用正则表达式,您必须知道您的数据是什么样子,并且它必须是一致且可预测的。在此示例中,我有一个日期时间字符串、一个 IPv4 地址,然后是括号内的消息。第一步是创建匹配这些不同元素的正则表达式模式。让我们从日期时间开始。

$t -match "\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}Z"

该模式表示,找到以 4 位数字开头的内容。 \d 表示一个数字,而 {4} 表示正好 4 个数字。然后是一个破折号,后跟 2 个数字 (\d{2}),另一个破折号和 2 个数字。那应该给我日期。但还有一点。我需要捕获空格 (\s),然后我有一个模式来匹配现在您应该识别的时间。结尾是一个字面Z

[玩转系统] 使用 PowerShell 和正则表达式捕获名称

正如你所看到的,这完全符合我想要的。顺便说一句,您通常可以编写不止一种模式。我试图坚持简单明了的模式。正则表达式可以够神秘的!

接下来,我需要匹配 IP 地址。

$t -match "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"

该模式表示以至少 1 位且不超过 3 位数字开头。 (\d{1,3}) 后跟一个句点。 (\.)。句点是一个特殊的正则表达式字符,它具有任何含义。\是转义字符,它告诉 PowerShell 查找文字句点。对于剩余的八位位组重复此模式。

[玩转系统] 使用 PowerShell 和正则表达式捕获名称

此模式不会验证地址,只是验证它看起来像一个IP地址。有些模式具有更多限制,但我不想增加任何更多的复杂性。在我的情况下,我知道该地址是有效的。

最后是方括号之间的文本。

$t -match "\[.*\]"

括号是一个特殊的正则表达式字符,所以我需要对其进行转义。然后我要求匹配任何字符 (.) 的多个实例 (*)。

[玩转系统] 使用 PowerShell 和正则表达式捕获名称

定义名称

一旦有了匹配的模式,您就可以用名称来定义它们。总体布局如下所示:

(?<capture-name>Your-Pattern)

括号是关键。我的日期时间模式可以定义为命名捕获:

(?<date>\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}Z)

这是从头到尾描述整行文本的模式。

[regex]$rx = '(?<date>\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}Z)\s:\s(?<ip>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s\[\s(?<status>.*)\]'

我已经调整了最后一个模式以不包含括号。我还可以使用其他高级正则表达式技术,但我保持简单。需要注意的重要一点是,我将 $rx 定义为一种特殊类型的对象。这个正则表达式对象允许我做的事情不仅仅是简单地使用 -match 运算符。在这种情况下,我可以用它来查找匹配项。

[玩转系统] 使用 PowerShell 和正则表达式捕获名称

这很好。但这些名字是如何发挥作用的呢?

在 PowerShell 中使用命名捕获

在比赛中,您可以看到 Groups 属性。这是可以找到命名捕获的地方。

[玩转系统] 使用 PowerShell 和正则表达式捕获名称

使用 PowerShell,可以通过跳过第一个匹配组轻松仅获取指定的捕获。

[玩转系统] 使用 PowerShell 和正则表达式捕获名称

那几乎看起来像一个物体!创建一个实际的对象并不需要太多的时间。

$m.groups | Select-Object -Skip 1 | foreach-object -begin { $h = @{}  } -process {
    $h.Add($_.name,$_.value.trim())
} -end {
    [pscustomobject]$h
}

[玩转系统] 使用 PowerShell 和正则表达式捕获名称

不过,如果日期是日期时间对象而不是字符串,那就更好了。这是一个替代方案,假设您知道命名捕获的顺序。

$o = [pscustomobject]@{
    Date = $m.groups[1].value -as [datetime]
    IPAddress = $m.groups[2].value -as [ipaddress]
    Status = $m.groups[3].value 
}

正如你所看到的,这是一个对象。

[玩转系统] 使用 PowerShell 和正则表达式捕获名称

使用此代码,我可以编写一个脚本来处理日志文件的每一行,创建一个自定义对象。这使得过滤、排序或执行任何其他我需要对数据执行的操作变得更加容易。

从文本转换

或者更简单的方法怎么样?现在您已经知道如何使用命名捕获创建正则表达式模式,您可以使用我的 PSScriptTools 模块中的 ConvertFrom-Text 命令,您可以从 PowerShell 库安装该模块。使用此命令,您可以创建代码以将任何文本输出转换为 PowerShell 对象。

$c = "(?<Protocol>\w{3})\s+(?<LocalIP>(\d{1,3}\.){3}\d{1,3}):(?<LocalPort>\d+)\s+(?<ForeignIP>.*):(?<ForeignPort>\d+)\s+(?<State>\w+)?"
netstat -an | select -skip 4 | convertfrom-text $c | where-object {$_.LocalIP -ne '0.0.0.0'} | format-table -autosize

[玩转系统] 使用 PowerShell 和正则表达式捕获名称

一旦您至少掌握了一些基本的正则表达式技能,您就会发现自己经常使用它。与任何新语言一样,你使用它的次数越多,你就会变得越流利。

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯