about_Regular_Expressions

简短说明

介绍 PowerShell 中的正则表达式。

长说明

注意

本文介绍在 PowerShell 中使用正则表达式的语法和方法,并非所有语法都进行了讨论。 有关更完整的参考,请参阅正则表达式语言 - 快速参考

正则表达式是用于匹配文本的模式。 它可以由文本字符、运算符和其他构造组成。

本文演示 PowerShell 中的正则表达式语法。 PowerShell 具有使用正则表达式的多个运算符和 cmdlet。 可以在下面的链接中详细了解其语法和用法。

默认情况下,PowerShell 正则表达式不区分大小写。 上面所示的每种方法都有一种不同的方法来强制区分大小写。

  • 对于 Select-String,使用 CaseSensitive 参数。
  • 对于使用正则表达式的运算符,请使用区分大小写的版本:-cmatch-creplace-csplit
  • 对于 switch 语句,使用 -casesensitive 选项

字符文本

正则表达式可以是文本字符或字符串。 表达式使引擎与指定的文本完全匹配。

# This statement returns true because book contains the string "oo"
'book' -match 'oo'

字符类

虽然字符文本在知道确切的模式时工作,但字符类允许你不太具体。

字符组

[character group] 允许一次匹配任意数量的字符,而 [^character group] 仅匹配组中的字符 NOT。

# This expression returns true if the pattern matches big, bog, or bug.
'big' -match 'b[iou]g'

如果要匹配的字符列表包括连字符 (-),则它必须位于列表的开头或末尾,才能将其与字符范围表达式区分开来。

字符范围

模式也可以是一系列字符。 这些字符可以是字母 [A-Z]、数字 [0-9],甚至是基于 ASCII 的 [ -~](所有可打印字符)。

# This expression returns true if the pattern matches any 2 digit number.
42 -match '[0-9][0-9]'

数字

\d 字符类将与任何十进制数字匹配。 相反,\D 将匹配任何非十进制数字。

# This expression returns true if it matches a server name.
# (Server-01 - Server-99).
'Server-01' -match 'Server-\d\d'

单词字符

\w 字符类将与任何单词字符 [a-zA-Z_0-9] 匹配。 要匹配任何非单词字符,请使用 \W

# This expression returns true.
# The pattern matches the first word character 'B'.
'Book' -match '\w'

通配符

句点 (.) 是正则表达式中的通配符。 它将匹配除换行符 (\n) 之外的任何字符。

# This expression returns true.
# The pattern matches any 4 characters except the newline.
'a1\ ' -match '....'

空格

可以将任何空格字符与 \s 字符类匹配。 可以将任何非空格字符与 \S 匹配。 可以将文字空格字符与 匹配。

# This expression returns true.
# The pattern uses the whitespace character class to match the leading
# space and a literal space to matching the trailing space.
' - ' -match '\s- '

数量词

限定符控制输入字符串中应存在的每个元素的实例数。

下面是 PowerShell 中提供的一些限定符:

限定符 说明
* 零次或多次。
+ 一次或多次。
? 零次或一次。
{n,m} 至少 n 次,但不超过 m 次。

星号 (*) 匹配上一个元素零次或多次。 结果是,即使没有元素的输入字符串也是匹配项。

# This returns true for all account name strings even if the name is absent.
'ACCOUNT NAME:    Administrator' -match 'ACCOUNT NAME:\s*\w*'

加号 (+) 匹配上一个元素一次或多次。

# This returns true if it matches any server name.
'DC-01' -match '[A-Z]+-\d\d'

问号 (?) 匹配上一个元素零次或一次。 与星号 * 一样,它甚至会匹配缺少元素的字符串。

# This returns true for any server name, even server names without dashes.
'SERVER01' -match '[A-Z]+-?\d\d'

可以使用 {n, m} 限定符的几种不同方法来对限定符进行精细控制。 第二个元素 m 和逗号 , 是可选的。

限定符 说明
{n} 完全匹配 n 次。
{n,} 至少匹配 n 次。
{n,m} 匹配 nm 次。
# This returns true if it matches any phone number.
'111-222-3333' -match '\d{3}-\d{3}-\d{4}'

定位点

通过定位点,可以根据输入字符串中的匹配位置导致匹配成功或失败。

这两个常用的定位点是 ^$。 插入符号 ^ 与字符串的开头匹配,$ 与字符串的末尾匹配。 通过定位点,可以在特定位置匹配文本,同时放弃不需要的字符。

# The pattern expects the string 'fish' to be the only thing on the line.
# This returns FALSE.
'fishing' -match '^fish$'

注意

定义包含 $ 定位点的正则表达式时,请务必使用单引号 (') 而不是双引号 (") 把正则表达式括起来,否则 PowerShell 将表达式扩展为变量。

在 PowerShell 中使用定位点时,应了解 SinglelineMultiline 正则表达式选项之间的差异。

  • Multiline:多行模式强制 ^$ 匹配每行的开头和结尾,而不是输入字符串的开头和结尾。
  • Singleline:单行模式将输入字符串视为 SingleLine。 它强制 . 字符匹配每个字符(包括换行符),而不是匹配除换行符 \n 之外的每个字符。

若要详细了解这些选项及其用法,请访问正则表达式语言 - 快速参考

转义字符

反斜杠 (\) 用于转义字符,以便正则表达式引擎不会分析它们。

保留以下字符:[]().\^$|?*+{}

需要在模式中转义这些字符以匹配输入字符串中的字符。

# This returns true and matches numbers with at least 2 digits of precision.
# The decimal point is escaped using the backslash.
'3.141' -match '3\.\d{2,}'

正则表达式类的静态方法可以转义文本。

[regex]::escape('3.\d{2,}')
3\.\\d\{2,}

注意

这会转义所有保留的正则表达式字符,包括字符类中使用的现有反斜杠。 请务必仅在需要转义的模式部分使用它。

其他字符转义符

还可以使用保留字符转义符来匹配特殊字符类型。

以下是一些常用的字符转义符:

字符转义符 说明
\t 与选项卡匹配
\n 与换行符匹配
\r 与回车符匹配

组、捕获和替换

分组构造将输入字符串分隔为可以捕获或忽略的子字符串。 分组子字符串称为子表达式。 默认情况下,子表达式在编号组中捕获,不过也可以为其分配名称。

分组构造是用括号括起来的正则表达式。 捕获由封闭正则表达式匹配的任何文本。 以下示例将输入文本拆分为两个捕获组。

'The last logged on user was CONTOSO\jsmith' -match '(.+was )(.+)'
True

使用 $MatchesHashtable 自动变量检索捕获的文本。 表示整个匹配项的文本存储在键 0。 请务必注意,$Matches 哈希表仅包含任何匹配模式的第一个匹配项。

$Matches.0
The last logged on user was CONTOSO\jsmith

捕获存储在数字 Integer 键中,这些键从左到右增加。 捕获 1 包含所有文本,直到用户名,捕获 2 仅包含用户名。

$Matches
Name           Value
----           -----
2              CONTOSO\jsmith
1              The last logged on user was
0              The last logged on user was CONTOSO\jsmith

重要

0 键为 Integer。 可以使用任何 Hashtable 方法来访问存储的值。

PS> 'Good Dog' -match 'Dog'
True

PS> $Matches[0]
Dog

PS> $Matches.Item(0)
Dog

PS> $Matches.0
Dog

命名捕获

默认情况下,捕获按从左到右的数字升序存储。 还可以将名称分配给捕获组。 此名称将成为 $MatchesHashtable 自动变量上的键。

在捕获组中,使用 ?<keyname> 在命名键下存储捕获的数据。

PS> $string = 'The last logged on user was CONTOSO\jsmith'
PS> $string -match 'was (?<domain>.+)\\(?<user>.+)'
True

PS> $Matches

Name                           Value
----                           -----
domain                         CONTOSO
user                           jsmith
0                              was CONTOSO\jsmith

PS> $Matches.domain
CONTOSO

PS> $Matches.user
jsmith

以下示例将最新的日志条目存储在 Windows 安全日志中。 提供的正则表达式从消息中提取用户名和域,并将其存储在键下:N 用于名称,D 用于域。

$log = (Get-WinEvent -LogName Security -MaxEvents 1).message
$r = '(?s).*Account Name:\s*(?<N>.*).*Account Domain:\s*(?<D>[A-Z,0-9]*)'
$log -match $r
True
$Matches
Name                           Value
----                           -----
D                              CONTOSO
N                              jsmith
0                              A process has exited....

有关更多信息,请参阅正则表达式中的分组构造

正则表达式中的替代

通过运算符使用正则表达式(regex), -replace 可以使用捕获的文本动态替换文本。

<input> -replace <original>, <substitute>

  • <input>:要搜索的字符串
  • <original>:用于搜索输入字符串的正则表达式
  • <substitute>:一个正则表达式替换表达式,用于替换输入字符串中找到的匹配项。

<original><substitute>操作数受正则表达式引擎的规则(如字符转义或替换表达式)的约束。 替换模式可以包含一个或多个替换以及本文字符。

可以使用组标识符前的$字符在字符串中<substitute>引用捕获组。

引用捕获组的两种方法是按数字和按名称

  • 数字 - 捕获组从左到右编号。

    'John D. Smith' -replace '(\w+) (\w+)\. (\w+)', '$1.$2.$3@contoso.com'
    
    John.D.Smith@contoso.com
    
  • 名称 - 捕获组也可以按名称引用。

    'CONTOSO\Administrator' -replace '\w+\\(?<user>\w+)', 'FABRIKAM\${user}'
    
    FABRIKAM\Administrator
    

$& 表达式表示匹配的所有文本。

'Gobble' -replace 'Gobble', '$& $&'
Gobble Gobble

警告

由于在字符串扩展中使用 $ 字符,因此在使用双引号时,需要使用带替换的文本字符串,或转义 $ 字符。

'Hello World' -replace '(\w+) \w+', '$1 Universe'
"Hello World" -replace "(\w+) \w+", "`$1 Universe"
Hello Universe
Hello Universe

此外,如果要将 $ 用作文本字符,请使用 $$ 而不是普通转义字符。 使用双引号时,仍转义 $ 的所有实例以避免不正确的替换。

'5.72' -replace '(.+)', '$$$1'
"5.72" -replace "(.+)", "`$`$`$1"
$5.72
$5.72

有关替换表达式的详细信息,请参阅 正则表达式中的替换。

另请参阅