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

[玩转系统] 关于比较运算符

作者:精品下载站 日期:2024-12-14 02:23:45 浏览:13 分类:玩电脑

关于比较运算符


简短描述

PowerShell 中的比较运算符可以比较两个值,也可以根据输入值过滤集合的元素。

详细描述

比较运算符允许您比较值或查找与指定模式匹配的值。 PowerShell 包括以下比较运算符:

平等

  • -eq-ieq-ceq - 等于
  • -ne-ine-cne - 不等于
  • -gt-igt-cgt - 大于
  • -ge-ige-cge - 大于或等于
  • -lt-ilt-clt - 小于
  • -le-ile-cle - 小于或等于

匹配

  • -like-ilike-clike - 字符串与通配符模式匹配
  • -notlike-inotlike-cnotlike - 字符串与通配符模式不匹配
  • -match-imatch-cmatch - 字符串与正则表达式模式匹配
  • -notmatch-inotmatch-cnotmatch - 字符串与正则表达式模式不匹配

更换

  • -replace-ireplace-creplace - 替换与正则表达式模式匹配的字符串

遏制

  • -contains-icontains-ccontains - 集合包含一个值
  • -notcontains-inotcontains-cnotcontains - 集合不包含值
  • -in - 值在集合中
  • -notin - 值不在集合中

类型

  • -is - 两个对象是同一类型
  • -isnot - 对象不是同一类型

共同特点

字符串比较不区分大小写,除非您使用显式区分大小写的运算符。要使比较运算符区分大小写,请在 - 之后添加 c。例如,-ceq-eq 的区分大小写的版本。要明确区分大小写,请在 - 之后添加 i。例如,-ieq-eq 的显式不区分大小写的版本。

字符串比较使用 InvariantCulture 进行区分大小写和不区分大小写的比较。比较是在 unicode 代码点之间进行的,并且不使用特定于区域性的排序规则。无论当前文化如何,结果都是相同的。

当比较表达式中的左侧值为标量值时,该运算符返回一个布尔值。当表达式中左侧值是集合时,该运算符返回与表达式右侧值匹配的集合元素。右侧值始终被视为单例实例,即使它们是集合也是如此。比较运算符无法有效地比较集合与集合。

如果集合中没有匹配项,比较运算符将返回一个空数组。例如:

$a = (1, 2) -eq 3
$a.GetType().Name
$a.Count
Object[]
0

有一些例外:

  • 包含和类型运算符始终返回布尔
  • -replace 运算符返回替换结果
  • -match-notmatch 运算符也会填充 $Matches 自动变量,除非表达式的左侧是集合。

相等运算符

-eq-ne

当左侧为标量时,如果右侧相等,-eq 返回 True,否则 -eq 返回 >错误-ne 则相反;当双方相等时返回False;否则,-ne 返回True

例子 :

2 -eq 2                 # Output: True
2 -eq 3                 # Output: False
"abc" -eq "abc"         # Output: True
"abc" -eq "abc", "def"  # Output: False
"abc" -ne "def"         # Output: True
"abc" -ne "abc"         # Output: False
"abc" -ne "abc", "def"  # Output: True

当左侧是集合时,-eq 返回与右侧匹配的成员,而 -ne 则将其过滤掉。

例子 :

1,2,3 -eq 2             # Output: 2
"abc", "def" -eq "abc"  # Output: abc
"abc", "def" -ne "abc"  # Output: def

这些运算符处理集合的所有元素。例子:

"zzz", "def", "zzz" -eq "zzz"
zzz
zzz

相等运算符可以比较不同类型的对象。重要的是要了解比较右侧的值可以转换为左侧值的类型以进行比较。

例如,字符串 '1.0' 被转换为整数以与值 1 进行比较。此示例返回 True

PS> 1 -eq '1.0'
True

在此示例中,值 1 被转换为字符串以与字符串 '1.0' 进行比较。此示例返回 False

PS> '1.0' -eq 1
False

相等运算符接受任意两个对象,而不仅仅是标量或集合。但不能保证比较结果对最终用户有意义。以下示例演示了该问题。

class MyFileInfoSet {
    [String]$File
    [Int64]$Size
}
$a = [MyFileInfoSet]@{File = "C:\Windows\explorer.exe"; Size = 4651032}
$b = [MyFileInfoSet]@{File = "C:\Windows\explorer.exe"; Size = 4651032}
$a -eq $b
False

在此示例中,我们创建了两个具有相同属性的对象。然而,相等性测试结果为False,因为它们是不同的对象。要创建类似的类,您需要在类中实现 System.IEquatable。以下示例演示了 MyFileInfoSet 类的部分实现,该类实现 System.IEquatable 并具有两个属性:FileSize。如果两个 MyFileInfoSet 对象的 File 和 Size 属性相同,则 Equals() 方法返回 True

class MyFileInfoSet : System.IEquatable[Object] {
    [String]$File
    [Int64]$Size

    [bool] Equals([Object] $obj) {
        return ($this.File -eq $obj.File) -and ($this.Size -eq $obj.Size)
    }
}
$a = [MyFileInfoSet]@{File = "C:\Windows\explorer.exe"; Size = 4651032}
$b = [MyFileInfoSet]@{File = "C:\Windows\explorer.exe"; Size = 4651032}
$a -eq $b
True

比较任意对象的一个突出例子是找出它们是否为空。但如果您需要确定变量是否为 $null,则必须将 $null 放在相等运算符的左侧。将其放在右侧不会达到您的预期。

例如,令 $a 为包含 null 元素的数组:

$a = 1, 2, $null, 4, $null, 6

以下测试 $a 不为 null。

$null -ne $a
True

但是,以下代码会从 $a 中筛选出所有 null 元素:

$a -ne $null # Output: 1, 2, 4, 6
1
2
4
6

-gt-ge-lt-le

-gt-ge-lt-le 的行为非常相似。当两边都是标量时,它们返回 TrueFalse,具体取决于两边的比较:

-gt

左边更大

-ge

左边大于或等于

-lt

左侧较小

-le

左边较小或等于

在以下示例中,所有语句都返回 True

8 -gt 6  # Output: True
8 -ge 8  # Output: True
6 -lt 8  # Output: True
8 -le 8  # Output: True

笔记

在大多数编程语言中,大于运算符是>。在 PowerShell 中,该字符用于重定向。详情请参见about_Redirection。

当左侧是集合时,这些运算符将集合的每个成员与右侧进行比较。根据他们的逻辑,他们要么保留或丢弃该成员。

例子 :

$a=5, 6, 7, 8, 9

Write-Output "Test collection:"
$a

Write-Output "`nMembers greater than 7"
$a -gt 7

Write-Output "`nMembers greater than or equal to 7"
$a -ge 7

Write-Output "`nMembers smaller than 7"
$a -lt 7

Write-Output "`nMembers smaller than or equal to 7"
$a -le 7
Test collection:
5
6
7
8
9

Members greater than 7
8
9

Members greater than or equal to 7
7
8
9

Members smaller than 7
5
6

Members smaller than or equal to 7
5
6
7

这些运算符可与任何实现 System.IComparable 的类一起使用。

示例:

# Date comparison
[DateTime]'2001-11-12' -lt [DateTime]'2020-08-01' # True

# Sorting order comparison
'a' -lt 'z'           # True; 'a' comes before 'z'
'macOS' -ilt 'MacOS'  # False
'MacOS' -ilt 'macOS'  # False
'macOS' -clt 'MacOS'  # True; 'm' comes before 'M'

以下示例演示了美式 QWERTY 键盘上没有在“a”之后排序的符号。它将包含所有此类符号的集合提供给 -gt 运算符,以将它们与“a”进行比较。输出是一个空数组。

$a=' ','`','~','!','@','#','$','%','^','&','*','(',')','_','+','-','=',
   '{','}','[',']',':',';','"','''','\','|','/','?','.','>',',','<'
$a -gt 'a'
# Output: Nothing

如果运算符的两侧不具有合理的可比性,则这些运算符会引发非终止错误。

匹配运算符

匹配运算符(-like-notlike-match-notmatch)查找匹配或的元素与指定模式不匹配。 -like-notlike 的模式是通配符表达式(包含 *? [ ]),而 -match-notmatch 接受正则表达式 (Regex)。

语法是:

<string[]> -like    <wildcard-expression>
<string[]> -notlike <wildcard-expression>
<string[]> -match    <regular-expression>
<string[]> -notmatch <regular-expression>

当这些运算符的输入是标量值时,它们返回一个布尔值。

当输入是值的集合时,集合中的每个项目都会转换为字符串以进行比较。 -match-notmatch 运算符分别返回任何匹配和不匹配的成员。但是,-like-notlike 运算符将成员作为字符串返回。 -like-notlike 为集合成员返回的字符串是运算符用于比较的字符串,是通过将成员强制转换为字符串而获得的。

-like-notlike

-like-notlike 的行为与 -eq-ne 类似,但右侧可能是包含通配符的字符串。

例子 :

"PowerShell" -like    "*shell"           # Output: True
"PowerShell" -notlike "*shell"           # Output: False
"PowerShell" -like    "Power?hell"       # Output: True
"PowerShell" -notlike "Power?hell"       # Output: False
"PowerShell" -like    "Power[p-w]hell"   # Output: True
"PowerShell" -notlike "Power[p-w]hell"   # Output: False

"PowerShell", "Server" -like "*shell"    # Output: PowerShell
"PowerShell", "Server" -notlike "*shell" # Output: Server

-match-notmatch

-match-notmatch 使用正则表达式在左侧值中搜索模式。正则表达式可以匹配复杂的模式,例如电子邮件地址、UNC 路径或格式化的电话号码。右侧字符串必须遵守正则表达式规则。

标量示例:

# Partial match test, showing how differently -match and -like behave
"PowerShell" -match 'shell'        # Output: True
"PowerShell" -like  'shell'        # Output: False

# Regex syntax test
"PowerShell" -match    '^Power\w+' # Output: True
'bag'        -notmatch 'b[iou]g'   # Output: True

如果输入是集合,则运算符返回该集合的匹配成员。

集合示例:

"PowerShell", "Super PowerShell", "Power's hell" -match '^Power\w+'
# Output: PowerShell

"Rhell", "Chell", "Mel", "Smell", "Shell" -match "hell"
# Output: Rhell, Chell, Shell

"Bag", "Beg", "Big", "Bog", "Bug"  -match 'b[iou]g'
#Output: Big, Bog, Bug

"Bag", "Beg", "Big", "Bog", "Bug"  -notmatch 'b[iou]g'
#Output: Bag, Beg

-match-notmatch 支持正则表达式捕获组。每次它们在标量输入上运行时,-match 结果为 True,或 -notmatch 结果为 False >,它们会覆盖 $Matches 自动变量。 $Matches 是一个哈希表,它始终有一个名为“0”的键,用于存储整个匹配项。如果正则表达式包含捕获组,则 $Matches 包含每个组的附加键。

请务必注意,$Matches 哈希表仅包含任何匹配模式的第一次出现。

例子 :

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

$Matches

Write-Output "`nDomain name:"
$Matches.domain

Write-Output "`nUser name:"
$Matches.user
True

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

Domain name:
CONTOSO

User name:
jsmith

-match结果为False,或者-notmatch结果为True,或者当输入是集合中,$Matches 自动变量不会被覆盖。因此,它将包含先前设置的值,或者如果尚未设置变量,则包含 $null。在调用这些运算符之一后引用 $Matches 时,请考虑使用条件语句验证该变量是否由当前运算符调用设置。

例子 :

if ("<version>1.0.0</version>" -match '<version>(.*?)</version>') {
    $Matches
}

有关详细信息,请参阅 about_Regular_Expressions 和 about_Automatic_Variables。

更换操作员

用正则表达式替换

-match 一样,-replace 运算符使用正则表达式来查找指定模式。但与 -match 不同的是,它用另一个指定的值替换匹配项。

语法:

<input> -replace <regular-expression>, <substitute>

该运算符使用正则表达式将值的全部或部分替换为指定值。您可以使用该运算符执行许多管理任务,例如重命名文件。例如,以下命令将所有 .txt 文件的文件扩展名更改为 .log

Get-ChildItem *.txt | Rename-Item -NewName { $_.name -replace '\.txt$','.log' }

默认情况下,-replace 运算符不区分大小写。要使其区分大小写,请使用 -creplace。要使其显式不区分大小写,请使用 -ireplace

示例:

"book" -ireplace "B", "C" # Case insensitive
"book" -creplace "B", "C" # Case-sensitive; hence, nothing to replace
Cook
book

从 PowerShell 7.2 开始,当 -replace 运算符语句中的左侧操作数不是字符串时,该操作数将转换为字符串。 PowerShell 执行不区分区域性的字符串转换。

例如,如果您的区域性设置为法语 (fr),则值 1.2 的区域性敏感字符串转换为 1,2

PowerShell 7.2 之前的版本:

PS> [cultureinfo]::CurrentCulture = 'fr'
PS> 1.2 -replace ','
12

在 PowerShell 7.2 及更高版本中:

PS> [cultureinfo]::CurrentCulture = 'fr'
PS> 1.2 -replace ','
1.2

正则表达式替换

还可以使用正则表达式通过捕获组和替换来动态替换文本。可以在组标识符之前使用美元符号 ($) 字符在 <substitute> 字符串中引用捕获组。

在以下示例中,-replace 运算符接受 DomainName\Username 形式的用户名,并转换为 Username@DomainName 格式:

$SearchExp = '^(?<DomainName>[\w-.]+)\(?<Username>[\w-.]+)$'
$ReplaceExp = '${Username}@${DomainName}'

'Contoso.local\John.Doe' -replace $SearchExp, $ReplaceExp
[email protected]

警告

$ 字符在 PowerShell 和正则表达式中都具有语法作用:

  • 在 PowerShell 中,它位于双引号之间,指定变量并充当子表达式运算符。
  • 在正则表达式搜索字符串中,它表示行尾。
  • 在正则表达式替换字符串中,它表示捕获的组。请务必将正则表达式放在单引号之间或在它们之前插入反引号 (`) 字符。

例如:

$1 = 'Goodbye'

'Hello World' -replace '(\w+) \w+', "$1 Universe"
# Output: Goodbye Universe

'Hello World' -replace '(\w+) \w+', '$1 Universe'
# Output: Hello Universe

正则表达式中的 $$ 表示文字 $。替换字符串中的此 $$ 会在结果替换中包含文字 $。例如:

'5.72' -replace '(.+)', '$ $1' # Output: $ 5.72
'5.72' -replace '(.+)', '$$$1' # Output: $5.72
'5.72' -replace '(.+)', '$$1'  # Output: $1

要了解更多信息,请参阅 about_Regular_Expressions 和正则表达式中的替换。

在集合中替换

-replace 运算符的 <input> 是集合时,PowerShell 将替换应用于集合中的每个值。例如:

"B1","B2","B3","B4","B5" -replace "B", 'a'
a1
a2
a3
a4
a5

用脚本块替换

在 PowerShell 6 及更高版本中,-replace 运算符还接受执行替换的脚本块。该脚本块每场比赛运行一次。

语法:

<String> -replace <regular-expression>, {<Script-block>}

在脚本块中,使用 $_ 自动变量来访问要替换的输入文本和其他有用信息。该变量的类类型是System.Text.RegularExpressions.Match。

以下示例将每个三位数序列替换为等效字符。该脚本块针对需要替换的每组三个数字运行。

"072101108108111" -replace "\d{3}", {return [char][int]$_.Value}
Hello

收容运营商

包含运算符(-contains-notcontains-in-notin)与等式类似运算符,不同之处在于它们始终返回布尔值,即使输入是集合也是如此。这些运算符在检测到第一个匹配项后立即停止比较,而相等运算符则评估所有输入成员。在非常大的集合中,这些运算符比相等运算符返回得更快。

-包含-notcontains

语法:

<Collection> -contains <scalar-object>
<Collection> -notcontains <scalar-object>

这些运算符判断集合是否包含某个元素。当右侧(标量对象)与集合中的元素之一匹配时,-contains 返回True-notcontains 返回 False。

示例:

"abc", "def" -contains "def"                  # Output: True
"abc", "def" -notcontains "def"               # Output: False
"Windows", "PowerShell" -contains "Shell"     # Output: False
"Windows", "PowerShell" -notcontains "Shell"  # Output: True
"abc", "def", "ghi" -contains "abc", "def"    # Output: False
"abc", "def", "ghi" -notcontains "abc", "def" # Output: True

更复杂的例子:

$DomainServers = "ContosoDC1","ContosoDC2","ContosoFileServer","ContosoDNS",
                 "ContosoDHCP","ContosoWSUS"
$thisComputer  = "ContosoDC2"

$DomainServers -contains $thisComputer
# Output: True

当右侧操作数是集合时,这些运算符会先将值转换为其字符串表示形式,然后再将其与左侧集合进行比较。

$a = "abc", "def"
"abc", "def", "ghi" -contains $a # Output: False

# The following statements are equivalent
$a, "ghi" -contains $a           # Output: True
"$a", "ghi" -contains $a         # Output: True
"abc def", "ghi" -contains $a    # Output: True

-in-notin

语法:

<scalar-object> -in <Collection>
<scalar-object> -notin <Collection>

-in-notin 运算符在 PowerShell 3 中引入,作为 -contains-notcontains 运算符。当左侧 <scalar-object> 与集合中的元素之一匹配时,-in 返回 True-notin 返回 False

以下示例与 -contains-notcontains 的示例执行相同的操作,但它们是用 -in 编写的>-notin 相反。

"def" -in "abc", "def"                  # Output: True
"def" -notin "abc", "def"               # Output: False
"Shell" -in "Windows", "PowerShell"     # Output: False
"Shell" -notin "Windows", "PowerShell"  # Output: True
"abc", "def" -in "abc", "def", "ghi"    # Output: False
"abc", "def" -notin "abc", "def", "ghi" # Output: True

更复杂的例子:

$DomainServers = "ContosoDC1","ContosoDC2","ContosoFileServer","ContosoDNS",
                 "ContosoDHCP","ContosoWSUS"
$thisComputer  = "ContosoDC2"

$thisComputer -in $DomainServers
# Output: True

当左侧操作数是集合时,这些运算符会先将值转换为其字符串表示形式,然后再将其与右侧集合进行比较。

$a = "abc", "def"
$a -in "abc", "def", "ghi" # Output: False

# The following statements are equivalent
$a -in $a, "ghi"           # Output: True
$a -in "$a", "ghi"         # Output: True
$a -in "abc def", "ghi"    # Output: True

类型比较

类型比较运算符(-is-isnot)用于确定对象是否为特定类型。

语法:

<object> -is <type-reference>
<object> -isnot <type-reference>

例子 :

$a = 1
$b = "1"
$a -is [int]           # Output: True
$a -is $b.GetType()    # Output: False
$b -isnot [int]        # Output: True
$a -isnot $b.GetType() # Output: True

参见

  • about_布尔值
  • about_Operators
  • about_Regular_Expressions
  • about_通配符
  • Compare-Object
  • Foreach-Object
  • Where-Object

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

取消回复欢迎 发表评论:

关灯