入门

PowerShell默认的匹配规则不区分大小写。比如“Don”,从技术角度来说,这就是一个正则表达式,在PowerShell中能够匹配“DON”“don”“Don”“DoN”等

下面是一些常用的正则表达式字符规则:

  • \w用于匹配“文本字符”,也就是字母、数字以及下划线,但不包含标点符号和空格。
    • 正则表达式\won可以匹配“Don”“Ron”以及“ton”, \w可以代表任意字母、数字或下划线。
  • \W与 \w相反,意思是它将会匹配空格与标点符号——也就是“非字母”。
  • \d用于匹配包括0到9的任意数字。
  • \D用于匹配任意非数字。
  • \s用于匹配任意空格字符,比如Tab、空格或者回车符。
  • \S用于匹配任意非空格字符。
  • .(句号)代表任意单个字符。
  • [abcde]用于匹配在该集合中的任意字符。
    • 正则表达式d[aeiou]n可以匹配“Don”“Dan”,但不会匹配“Doun”或“Deen”。
  • [a-z]匹配在此范围内的一个或多个字符,可以使用逗号分隔列表指定多个范围,比如说[a-f,m-z]。
  • [^abcde]用于匹配不在该集合中的一个或多个字符。
    • 正则表达式d[^aeiou]可以与“dns”匹配,但无法与“don”匹配。
  • 置于另一个字母或特殊符号之后,可以用于匹配该字符的一个实例;?还可以代表空实例
    • 正则表达式do?n可以与“don”匹配,但不会与“doon”匹配。该正则表达式还可以与“dn”匹配
  • *用于匹配该符号之前任意数量的实例;*还可以代表空实例
    • 正则表达式do*n将会与“doon”和“don”匹配。该正则表达式还可以与“dn”匹配。
  • + 用于匹配该符号之前任意数量的实例。你会经常见到该字符和括号一起使用,从而创建了一种子表达式。
    • 如(dn)+o可以与“dndndndno”匹配,这是由于该正则表达式可以重复匹配子表达式“dn”。
  • \(反斜杠)是正则表达式转义字符。将该字符置于在正则表达式中有特殊意义的字符之前,从而使得该字符变为该字符的字面意思。
    • 比如,正则表达式\.仅仅匹配一个句号,而不是像正常情况那样用于代表任意单个字符。
    • 如果希望匹配反斜杠,那么在反斜杠之前再加一个反斜杠:\\
  • {2}用于匹配该符号之前特定数量的实例。
    • 比如,\d{1}用于匹配1个数字。使用{2, }匹配2或多个数字,使用{1,3}匹配至少1个但不超过3个实例。
  • ^用于匹配字符串开始部分。
    • 比如,正则表达式d.n既可以匹配“don”,又可以匹配“pteranodon”。
    • 而正则表达式^d.n只能匹配“don”,而无法匹配“pteranodon”。这是由于^使得匹配只能从字符串开始部分匹配,而^与[]共同使用时表达取匹配的反义
  • $用于匹配字符串结尾部分。
    • 比如,正则表达式.icks既可以与“hicks”匹配,又与“sticks”匹配,还能与“Dickson”匹配。
    • 但正则表达式.icks$无法与“Dickson”匹配,这是因为$表示字符“s”应该是该字符串的最后一个字符。

可以通过在PowerShell运行help [about_regular_expressions](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_regular_expressions?view=powershell-7.2),发现更多关于正则表达式的基本语法。

正则匹配范例

1)\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}可以匹配IPv4地址的模式,但该表达式可以接受“432.567.875.000”这样的非法地址,也可以接受“192.169.15.12”这样的合法地址。
2)\\\\\w+(\\\w+)+可以匹配通用命名惯例(UNC)路径。大量的反斜杠使得该正则表达式难以阅读,这也是为什么在将正则表达式部署到生产环境之前对正则表达式进行调试和调整。
3)\w{1}\.\w+@company\.com可以匹配特定类型的电子邮件地址:首先是一个字母,然后是句号,最后是“@company.com”。

  • 比如d.jones@company.com可以与该正则表达式进行匹配,“donald . jones@company. com.org”也能够匹配。
  • 正则表达式允许在匹配文本的开始或结尾存在额外的字符。在这种情况下,就可以考虑使用^或$。

    通过-Match测试正则表达式

    PowerShell包含一个比较运算符-Match,以及一个区分大小写版本的-Cmatch。通过这两个运算符与正则表达式进行比较。
    image.png
    如果两端匹配,那么输出True;如果两端不匹配,那么输出False。

    通过Select-String使用正则表达式

    让我们先在日志文件中查找40x错误。这类错误主要是“找不到文件”以及其他错误,我们希望为Web开发人员生成一个缺失文件的报表。日志文件中,每一个HTTP请求为一行,每行又被分为以空格分割的域。
    还有一些文件名称中包含“401”等,比如“error401.html”,我们不希望这部分结果出现在结果中。我们将会指定一个类似\s40[0-9]\s的正则表达式,因为通过在40x错误之前和之后匹配空格,该表达式将能够匹配从400到499的错误。下面是我们使用的命令。
    1. PS C:\logfiles> Get-ChildItem -Filter *.log -Recurse |
    2. Select-String -Pattern "\s40[0-9]\s" |
    3. Format-Table FileName, LineNumber, Line -Wrap
    该命令的结果是一个类型为MatchInfo的对象。

接下来,我们希望扫描所有被基于Gecko浏览器访问过的文件。开发人员告诉我们,使用该类浏览器访问我们网站的用户会遇到一些问题,他们希望找到具体被访问的文件。他们还希望将问题范围缩减为使用Windows NT6.2操作系统运行浏览器的用户,这意味着我们需要在user-agnet中寻找类似下面的字符串。
image.png
开发人员强调是否为64位操作系统无关紧要,因此我们不希望User-agent中仅是包含“WOW64”的结果。最终我们得到这个正则表达式:6\.2; [\w\W]+\+Gecko——让我们对其进行分解。

  • 6\.2;:即“6.2”;我们使用转义字符将句号变为字面意思上的句号,而不是作为单字符的通配符。
  • [\w\W]+:一个或多个字符或非字符——换句话说是任何内容。
  • \+Gecko:也就是字面意义上的加号,然后是“Gecko”。

下面是从日志文件返回匹配行的命令,还包含前几行的返回结果。
image.png

在最后一个例子中,将IIS日志文件变为Windows安全日志。事件日志实体中包含Message属性,该属性中包含关于事件信息的细节。我们希望查找所有事件ID为4624的事件,该事件代表账户登录事件。但我们只希望查看账户名称以“WIN”开头的登录信息,这些账户都与在域中的计算机账户关联。另外,我们还要求账户结尾必须是从TM20$到TM40$的字符,这些是我们感兴趣的特定计算机。
正则表达式大概如下:WIN[\W\w]+TM[234][0-9]\$ ——此处需要使用转义符号将末尾的$进行转义,因此该符号不会被解释成字符串结尾标记。需要包含[\W\w](非字符和字符),这是由于我们的账户名称中可能包含连字符,该连字符无法与\w字符类匹配。因此最终下面是我们的命令。
image.png
在开始部分,我们使用Where-Object,从而仅使得ID为4624的事件被筛选出来。然后我们将Message属性的内容存入纯字符串,并通过管道将其传输给Select-String。
注意,这将会输出匹配的信息文本;如果我们的目标是输出所有匹配的事件,就需要使用另一种方式。
image.png
这里,我们不是输出Message属性的内容,而是查找Message属性匹配正则表达式的记录——接下来输出整个Event对象。

进一步学习

在PowerShell的其他地方也可以使用正则表达式:

  • Switch脚本构造器中包含一个参数,使得其值可以与一个或多个正则表达式进行比较。
  • 高级脚本和函数(脚本Cmdlets)可以使用一个基于正则表达式的输入验证工具,以防止无效的参数值。
  • -Match运算符将字符串与正则表达式进行对比。还有一部分——抓取匹配的字符串存入一个自动的$matches集合。

如果希望更深入地学习,我们推荐你阅读JeffreyE.F.Friedl的著作Mastering Regular Expressions(O’Reilly出版社,2006)。
在线正则表达式资源:http://RegExLib.com。该网站包含用于不同目的的大量正则表达式示例(电话号码、邮件地址、IP地址等)。可以使用http://RegExTester.com这个网站测试正则表达式,从而确保正则表达式能够满足我们的需求。