7. 表达式

编辑说明

重要

Windows PowerShell 语言规范 3.0 于 2012 年 12 月发布,基于 Windows PowerShell 3.0。 此规范不反映 PowerShell 的当前状态。 没有计划更新本文档以反映当前状态。 此处提供了本文档供历史参考。

规格说明文档可以作为 Microsoft Word 文档从 Microsoft 下载中心获取:https://www.microsoft.com/download/details.aspx?id=36389 该 Word 文档已在 Microsoft Learn 上转换为展示用途。 转换期间,进行了一些编辑更改,以适应 Docs 平台的格式设置。 已更正某些拼写错误和次要错误。

语法:

expression:
    primary-expression
    bitwise-expression
    logical-expression
    comparison-expression
    additive-expression
    multiplicative-expression

dash: one of
    - (U+002D)
    EnDash character (U+2013)
    EmDash character (U+2014)
    Horizontal bar character (U+2015)

dashdash:
    dash dash

描述:

表达式 是由运算符和操作数构成的序列,用于表示方法、函数、可写位置或值;指定值的计算方式;可能产生一个或多个副作用;或执行上述元素的某种组合。 例如,

  • 字面值 123 是一个表示整数值 123 的表达式。
  • 表达式 1,2,3,4 指定显示值的 4 元素数组对象。
  • 表达式 10.4 * $a 指定计算。
  • 表达式 $a++ 会产生副作用。
  • 表达式 $a[$i--] = $b[++$j] 执行这些操作的组合。

除为某些运算符指定外,表达式中字词的计算顺序和副作用的发生顺序均未指定。 未指定行为的示例包括:$i++ + $i$i + --$i$w[$j++] = $v[$j]

PowerShell 的实现可能为用户定义的类型提供支持,并且这些类型可能具有对其定义的操作。 此类类型和操作的所有详细信息由实现定义。

顶级表达式不是某个更大表达式的一部分。 如果顶级表达式包含副作用运算符,则该表达式的值不会写入管道;否则,它会被写入。 有关此内容的详细讨论,请参阅 §7.1.1

通常,指定集合的表达式 ([§4§4]) 在使用该表达式的值时被枚举到其组成元素中。 但是,当表达式是 cmdlet 调用时,情况并非如此。 例如,

$x = 10,20,30
$a = $($x; 99)                     # $a.Length is 4

$x = New-Object 'int[]' 3
$a = $($x; 99)                     # equivalent, $a.Length is 4

$a = $(New-Object 'int[]' 3; 99)   # $a.Length is 2

$(...) 运算符的前两个用法中,指定集合的表达式是变量 $x,该变量枚举产生三个 int 值,加上 int 99。 但是,第三种情况下,表达式是对 cmdlet 的直接调用,因此不枚举结果,$a 是两个元素的数组,int[3]int

如果未由 PowerShell 定义操作,则会检查左操作数指定的值类型,以查看其是否有相应的 op_<operation> 方法。

7.1 主表达式

语法:

primary-expression:
    value
    member-access
    element-access
    invocation-expression
    post-increment-expression
    post-decrement-expression

value:
    parenthesized-expression
    sub-expression
    array-expression
    script-block-expression
    hash-literal-expression
    literal
    type-literal
    variable

7.1.1 分组括号

语法:

提示

语法定义中的 ~opt~ 表示法指示词法实体在语法中是可选的。

parenthesized-expression:
    ( new-lines~opt~ pipeline new-lines~opt~ )

描述:

括号表达式是一个 主表达式 其类型和值与没有括号的表达式的类型和值相同。 如果表达式指定变量,则括号表达式指定相同的变量。 例如,$x.m($x).m 等效。

可以在表达式中使用分组括号来记录该表达式中的默认优先级和关联性。 它们还可用于替代该默认优先级和关联性。 例如,

4 + 6 * 2    # 16
4 + (6 * 2)  # 16 document default precedence
(4 + 6) * 2  # 20 override default precedence

通常,在最顶层对括号进行分组是多余的。 但是,情况并非总是如此。 请考虑以下示例:

2,4,6       # Length 3; values 2,4,6
(2,4),6     # Length 2; values [object[]],int

第二种情况下,括号会更改语义,从而生成一个数组,其两个元素是包含两个整数的数组和标量整数 6。

下面是另一个例外:

23.5/2.4          # pipeline gets 9.79166666666667
$a = 1234 * 3.5   # value not written to pipeline
$a                # pipeline gets 4319

在第一种和第三种情况下,结果的值会被写入管道。 但是,虽然对第二种情况下的表达式进行了计算,但由于顶层存在副作用运算符 =,因此结果不会写入管道。 删除 $a = 部分可以使值被写入,因为 * 不是一个会产生副作用的运算符。

要防止任何不包含顶级副作用的表达式的值被写入管道,请显式丢弃该值,如下所示:

# None of these value are written to pipeline
[void](23.5/2.4)
[void]$a
$null = $a
$a > $null

若要向管道写入包含顶级副作用的任何表达式的值,请将该表达式括在括号中,如下所示:

($a = 1234 * 3.5) # pipeline gets 4319

因此,在这种情况下,分组括号不是冗余的。

在以下示例中,我们在字符串文本中进行了变量替换(§2.3.5.2):

">$($a = -23)<"    # value not written to pipeline, get ><
">$(($a = -23))<"  # pipeline gets >-23<

在第一种情况下,括号表示子表达式的分隔符,而不是分组括号,并且由于顶级表达式包含副作用运算符,因此表达式的值不会写入管道。 当然,>< 字符仍然写入。) 如果添加了分组括号(如第二种情况所示),则可以启用写入。

以下每个示例均包含顶层副作用运算符:

$a = $b = 0      # value not written to pipeline
$a = ($b = 0)    # value not written to pipeline
($a = ($b = 0))  # pipeline gets 0

++$a             # value not written to pipeline
(++$b)           # pipeline gets 1

$a--             # value not written to pipeline
($b--)           # pipeline gets 1

在不包含顶级副作用的表达式周围使用分组括号会使这些括号变得多余。 例如;

$a      # pipeline gets 0
($a)    # no side effect, so () redundant

考虑以下有两种副作用的示例,这两种副作用都不在顶级水平:

12.6 + ($a = 10 - ++$b) # pipeline gets 21.6.

结果被写入管道,因为顶级表达式没有副作用。

7.1.2 成员访问

语法:

member-access:
    primary-expression . new-line~opt~ member-name
    primary-expression :: new-line~opt~ member-name

请注意,主表达式后不允许空格。

描述:

运算符 . 用于从对象中选择实例成员,或从 Hashtable中选择键。 左侧操作数必须指定对象,右操作数必须指定可访问的实例成员。

右操作数指定左操作数指定对象类型的可访问实例成员,或者,如果左侧操作数指定数组,则右操作数指定数组的每个元素内的可访问实例成员。

不允许在 . 运算符之前使用空格。

此运算符是左结合运算符。

运算符 :: 用于从给定类型中选择静态成员。 左侧操作数必须指定一个类型,右侧操作数必须在该类型中指定可访问的静态成员。

不允许在 :: 运算符之前使用空格。

此运算符是左结合运算符。

如果右侧操作数在左操作数指定的对象类型内指定可写位置,则整个表达式指定可写位置。

例子:

$a = 10, 20, 30
$a.Length                    # get instance property

(10, 20, 30).Length

$property = "Length"
$a.$property                 # property name is a variable

$h1 = @{ FirstName = "James"; LastName = "Anderson"; IDNum = 123
}
$h1.FirstName                # designates the key FirstName
$h1.Keys                     # gets the collection of keys

[int]::MinValue              # get static property
[double]::PositiveInfinity   # get static property
$property = "MinValue"
[long]::$property            # property name is a variable

foreach ($t in [byte], [int], [long]) {
    $t::MaxValue             # get static property
}

$a = @{ID = 1 }, @{ID = 2 }, @{ID = 3 }
$a.ID                        # get ID from each element in the array

7.1.3 调用表达式

语法:

invocation-expression:
    primary-expression . new-line~opt~ member-name argument-list
    primary-expression :: new-line~opt~ member-name argument-list

argument-list:
    ( argument-expression-list~opt~ new-lines~opt~ )

请注意,主表达式后不允许空格。

描述:

invocation-expression 调用由 primary-expression.member-nameprimary-expression::member-name 所指定的方法。 argument-list 中的括号包含一个可能为空的逗号分隔的表达式列表,用于指定参数,其值将传递给方法。 在调用该方法之前,将按照 §6的规则计算和转换参数,以匹配方法预期的类型。 primary-expression.member-nameprimary-expression::member-name及其参数的计算顺序未指定。

此运算符是左结合运算符。

调用表达式 的结果的类型是 方法设计器§4.5.24)。

例子:

[math]::Sqrt(2.0)            # call method with argument 2.0
[char]::IsUpper("a")         # call method
$b = "abc#$%XYZabc"
$b.ToUpper()                 # call instance method

[math]::Sqrt(2)              # convert 2 to 2.0 and call method
[math]::Sqrt(2D)             # convert 2D to 2.0 and call method
[math]::Sqrt($true)          # convert $true to 1.0 and call method
[math]::Sqrt("20")           # convert "20" to 20 and call method

$a = [math]::Sqrt            # get method descriptor for Sqrt
$a.Invoke(2.0)               # call Sqrt via the descriptor
$a = [math]::("Sq"+"rt")     # get method descriptor for Sqrt
$a.Invoke(2.0)               # call Sqrt via the descriptor
$a = [char]::ToLower         # get method descriptor for ToLower
$a.Invoke("X")               # call ToLower via the descriptor

7.1.4 元素访问

语法:

element-access:
    primary-expression [ new-lines~opt~ expression new-lines~opt~ ]

描述:

主表达式 和左方括号([)之间不得有任何空格。

7.1.4.1 对数组进行下标操作

描述:

§9 中详细讨论了数组。 如果 表达式 是一维数组,请参阅 §7.1.4.5

主表达式 指定 A 的一维数组时,运算符 [] 返回 表达式 的值转换为 int后位于 A[0 + expression] 处的元素。 结果具有被下标的数组的元素类型。 如果 表达式 为负值,A[expression] 指定位于 A[A.Length + expression]的元素。

primary-expression 指定二维数组 B时,运算符 [] 在将表达式组件(指定为逗号分隔列表)的值转换为 int 后,返回位于 B[0 + row,0 + column] 的元素。 结果具有被下标的数组的元素类型。 与 1 维数组不同,负位置没有特殊含义。

主表达式 指定三个或更多个维度的数组时,将应用二维数组的规则,并将维度位置指定为逗号分隔的值列表。

如果尝试对一个不存在的元素进行读取操作,结果是 $null。 向不存在的元素写入是一个错误。

对于多维数组下标表达式,未指定维度位置表达式的计算顺序。 例如,给定一个三维数组 $a,则未指定 $a[$i++,$i,++$i] 的行为。

如果 表达式 是数组,请参阅 §7.1.4.5

此运算符是左结合运算符。

例子:

$a = [int[]](10,20,30) # [int[]], Length 3
$a[1] # returns int 20
$a[20] # no such position, returns $null
$a[-1] # returns int 30, i.e., $a[$a.Length-1]
$a[2] = 5 # changes int 30 to int 5
$a[20] = 5 # implementation-defined behavior

$a = New-Object 'double[,]' 3,2
$a[0,0] = 10.5 # changes 0.0 to 10.5
$a[0,0]++ # changes 10.5 to 10.6

$list = ("red",$true,10),20,(1.2, "yes")
$list[2][1] # returns string "yes"

$a = @{ A = 10 },@{ B = $true },@{ C = 123.45 }
$a[1]["B"] # $a[1] is a Hashtable, where B is a key

$a = "red","green"
$a[1][4] # returns string "n" from string in $a[1]

如果尝试对不存在的元素进行写入访问,则会引发 IndexOutOfRange 异常。

7.1.4.2 下标字符串

描述:

主表达式 指定字符串 S时,运算符 [] 返回 表达式指示的从零开始的位置中的字符作为字符。 如果 表达式 大于或等于该字符串的长度,则结果 $null。 如果 表达式 为负值,S[expression] 指定位于 S[S.Length + expression]的元素。

例子:

$s = "Hello"   # string, Length 5, positions 0-4
$c = $s[1]     # returns "e" as a string
$c = $s[20]    # no such position, returns $null
$c = $s[-1]    # returns "o", i.e., $s[$s.Length-1]

7.1.4.3 下标哈希表

描述:

主表达式 指定哈希表时,运算符 [] 返回与 表达式指定的键关联的值。 表达式 的类型不受限制。

表达式 为单个键名称时,结果是与之关联的值,并且为该类型,除非不存在此类键,在这种情况下,结果是 $null。 如果使用 $null 作为键,则行为是由实现决定的。 如果 表达式 是键名称数组,请参阅 §7.1.4.5

如果 表达式 是数组,请参阅 §7.1.4.5

例子:

$h1 = @{ FirstName = "James"; LastName = "Anderson"; IDNum = 123 }
$h1['FirstName']     # the value associated with key FirstName
$h1['BirthDate']     # no such key, returns $null

$h1 = @{ 10 = "James"; 20.5 = "Anderson"; $true = 123 }
$h1[10]              # returns value "James" using key 10
$h1[20.5]            # returns value "Anderson" using key 20.5
$h1[$true]           # returns value 123 using key $true

表达式 是单一键名时,如果 $null 用作哈希表的唯一下标值,则会引发 NullArrayIndex 异常。

7.1.4.4 在 XML 文档中使用下标

描述:

主表达式 指定 xml 类型的对象时,如有必要,表达式 转换为字符串,运算符 [] 返回具有由 表达式指定名称的第一个子元素。 表达式 的类型必须是字符串。 结果的类型由具体实现定义。 结果可以被下标以返回其第一个子元素。 如果表达式指定的名称不存在子元素,则结果为 $null。 结果未指定可写位置。

例子:

$x = [xml]@"
<Name>
<FirstName>Mary</FirstName>
<LastName>King</LastName>
</Name>
"@

$x['Name']                # refers to the element Name
$x['Name']['FirstName']   # refers to the element FirstName within Name
$x['FirstName']           # No such child element at the top level, result is $null

结果的类型为 System.Xml.XmlElementSystem.String

7.1.4.5 生成数组切片

主表达式 指定可枚举(§4)或哈希表类型的对象,并且 表达式 是一维数组时,结果是数组切片(§9.9),其中包含由 表达式元素指定的 主表达式 的元素。

对于哈希表,数组切片包含与指定键对应的值,如果不存在这样的键,则相应的元素为 $null。 如果将 $null 用作任何键名称,则行为是实现定义的。

例子:

$a = [int[]](30,40,50,60,70,80,90)
$a[1,3,5]                 # slice has Length 3, value 40,60,80
$a[,5]                    # slice with Length 1
$a[@()]                   # slice with Length 0
$a[-1..-3]                # slice with Length 3, value 90,80,70
$a = New-Object 'int[,]' 3,2
$a[0,0] = 10; $a[0,1] = 20; $a[1,0] = 30
$a[1,1] = 40; $a[2,0] = 50; $a[2,1] = 60
$a[(0,1),(1,0)]           # slice with Length 2, value 20,30, parens needed
$h1 = @{ FirstName = "James"; LastName = "Anderson"; IDNum = 123 }
$h1['FirstName']          # the value associated with key FirstName
$h1['BirthDate']          # no such key, returns $null
$h1['FirstName','IDNum']  # returns [object[]], Length 2 (James/123)
$h1['FirstName','xxx']    # returns [object[]], Length 2 (James/$null)
$h1[$null,'IDNum']        # returns [object[]], Length 2 ($null/123)

Windows PowerShell:当 表达式 是两个或多个键名的集合时,如果 $null 被用作某个键名称,该键会被忽略,并且在生成的数组中没有相应的元素。

7.1.5 后缀增量和减量运算符

语法:

post-increment-expression:
    primary-expression ++

post-decrement-expression:
    primary-expression dashdash

描述:

primary-expression 必须指定一个值为数值类型 (§4) 或值 $null 的可写位置。 如果操作数指定的值是 $null,那么在运算符计算之前,该值会先被转换为 int 类型,然后变为零。 存储结果时,主表达式 指定的值的类型可能会更改。 关于通过赋值进行类型更改的讨论,请参阅 §7.11

后缀 ++ 运算符生成的结果是操作数指定的值。 获取该结果后,操作数指定的值将按相应类型的 1 递增。 表达式结果 E++ 的类型与表达式 E + 1 的结果相同(§7.7)。

后缀 -- 运算符生成的结果是操作数指定的值。 获取该结果后,操作数指定的值将按相应类型的 1 递减。 表达式结果 E-- 的类型与表达式 E - 1 的结果相同(§7.7)。

这些运算符是左结合运算符。

例子:

$i = 0                # $i = 0
$i++                  # $i is incremented by 1
$j = $i--             # $j takes on the value of $i before the decrement

$a = 1,2,3
$b = 9,8,7
$i = 0
$j = 1
$b[$j--] = $a[$i++]   # $b[1] takes on the value of $a[0], then $j is
                      # decremented, $i incremented

$i = 2147483647       # $i holds a value of type int
$i++                  # $i now holds a value of type double because
                      # 2147483648 is too big to fit in type int

[int]$k = 0           # $k is constrained to int
$k = [int]::MaxValue  # $k is set to 2147483647
$k++                  # 2147483648 is too big to fit, imp-def behavior

$x = $null            # target is unconstrained, $null goes to [int]0
$x++                  # value treated as int, 0->1

7.1.6 $(...) 运算符

语法:

sub-expression:
    $( new-lines~opt~ statement-list~opt~ new-lines~opt~ )

描述:

如果省略 语句列表,则结果是 $null。 否则,将计算 statement-list。 作为评估过程的一部分而写入管道的任何对象都会按照顺序被收集到一个无限制的 1 维数组中。 如果收集的对象数组为空,则结果 $null。 如果收集的对象数组包含单个元素,则结果是该元素;否则,结果是未约束的收集结果的 1 维数组。

例子:

$j = 20
$($i = 10) # pipeline gets nothing
$(($i = 10)) # pipeline gets int 10
$($i = 10; $j) # pipeline gets int 20
$(($i = 10); $j) # pipeline gets [object[]](10,20)
$(($i = 10); ++$j) # pipeline gets int 10
$(($i = 10); (++$j)) # pipeline gets [object[]](10,22)
$($i = 10; ++$j) # pipeline gets nothing
$(2,4,6) # pipeline gets [object[]](2,4,6)

7.1.7 @(...) 运算符

语法:

array-expression:
    @( new-lines~opt~ statement-list~opt~ new-lines~opt~ )

描述:

如果省略 语句列表,则结果是长度为零的不受约束的 1 维数组。 否则,将对 statement-list 进行计算,并将作为计算一部分写入管道的任何对象按顺序收集在一个不受限制的一维数组中。 结果是(可能为空)不受约束的 1 维数组。

例子:

$j = 20
@($i = 10)             # 10 not written to pipeline, result is array of 0
@(($i = 10))           # pipeline gets 10, result is array of 1
@($i = 10; $j)         # 10 not written to pipeline, result is array of 1
@(($i = 10); $j)       # pipeline gets 10, result is array of 2
@(($i = 10); ++$j)     # pipeline gets 10, result is array of 1
@(($i = 10); (++$j))   # pipeline gets both values, result is array of 2
@($i = 10; ++$j)       # pipeline gets nothing, result is array of 0

$a = @(2,4,6)          # result is array of 3
@($a)                  # result is the same array of 3
@(@($a))               # result is the same array of 3

7.1.8 脚本块表达式

语法:

script-block-expression:
    { new-lines~opt~ script-block new-lines~opt~ }

script-block:
    param-block~opt~ statement-terminators~opt~ script-block-body~opt~

script-block-body:
    named-block-list
    statement-list

描述:

§8.10.9中介绍了 参数块named-block-list§8.10.7 中介绍。

脚本块是可用作单个单元的未命名语句块。 脚本块可用于调用代码块,就像它是单个命令一样,也可以将其分配给可以执行的变量。

执行 命名块列表语句列表,结果的类型和值是这些语句集的结果的类型和值。

script-block-expression 具有类型 scriptblock (§4.3.7)。

如果省略 参数块,则通过 $args§8.10.1)获取传递给脚本块的任何参数。

在参数绑定期间,脚本块可以作为脚本块对象传递,也可以在计算脚本块后作为结果传递。 有关详细信息,请参阅 §6.17

7.1.9 哈希文本表达式

语法:

hash-literal-expression:
    @{ new-lines~opt~ hash-literal-body~opt~ new-lines~opt~ }

hash-literal-body:
    hash-entry
    hash-literal-body statement-terminators hash-entry

hash-entry:
    key-expression = new-lines~opt~ statement

key-expression:
    simple-name
    unary-expression

statement-terminators:
    statement-terminator
    statement-terminators statement-terminator

statement-terminator:
    ;
    new-line-character

描述:

哈希文本表达式 用于创建零个或多个元素的哈希表(§10),每个元素都是键/值对。

键可能具有除 null 类型以外的任何类型。 关联的值可能具有任何类型,包括 null 类型,其中每个值可以是指定所需值的任何表达式,包括 $null

键/值对的顺序并不重要。

例子:

$h1 = @{ FirstName = "James"; LastName = "Anderson"; IDNum = 123 }
$last = "Anderson"; $IDNum = 120
$h2 = @{ FirstName = "James"; LastName = $last; IDNum = $IDNum + 3 }
$h3 = @{ }
$h4 = @{ 10 = "James"; 20.5 = "Anderson"; $true = 123 }

这将创建两个哈希表,$h1$h2,每个哈希表包含三个键/值对,第三个,$h3,即空。 哈希表 $h4 具有各种类型的键。

7.1.10 类型文本表达式

语法:

type-literal:
    [ type-spec ]

type-spec:
    array-type-name new-lines~opt~ dimension~opt~ ]
    generic-type-name new-lines~opt~ generic-type-arguments ]
    type-name

dimension:
    ,
    dimension ,

generic-type-arguments:
    type-spec new-lines~opt~
    generic-type-arguments , new-lines~opt~ type-spec

array-type-name:
    type-name [

generic-type-name:
    type-name [

描述:

在实现中,type-literal 由一些未指定的基础类型表示。 因此,类型名称是其基础类型的同义词。

类型文本用于许多上下文:

  • 指定显式转换(§6、§7.2.9
  • 创建类型约束数组(§9.4
  • 访问对象的静态成员(§7.1.2
  • 指定变量的类型约束(§5.3) 或函数参数(§8.10.2

例子:

[int].IsPrimitive        # $true
[Object[]].FullName      # "System.Object[]"
[int[,,]].GetArrayRank() # 3

专用于保存字符串的泛型堆栈类型(§4.4)可以编写为 [Stack[string]],专用于保存具有关联字符串值的 int 键的泛型字典类型可能编写为 [Dictionary[int,string]]

type-literal 的类型是 System.Type。 上面建议的类型 Stack[string] 的完整名称是 System.Collections.Generic.Stack[int]。 上面建议的类型 Dictionary[int,string] 的完整名称是 System.Collections.Generic.Dictionary[int,string]

7.2 一元运算符

语法:

unary-expression:
    primary-expression
    expression-with-unary-operator

expression-with-unary-operator:
    , new-lines~opt~ unary-expression
    -not new-lines~opt~ unary-expression
    ! new-lines~opt~ unary-expression
    -bnot new-lines~opt~ unary-expression
    + new-lines~opt~ unary-expression
    dash new-lines~opt~ unary-expression
    pre-increment-expression
    pre-decrement-expression
    cast-expression
    -split new-lines~opt~ unary-expression
    -join new-lines~opt~ unary-expression

pre-increment-expression:
    ++ new-lines~opt~ unary-expression

pre-decrement-expression:
    dashdash new-lines~opt~ unary-expression

dash: one of
    - (U+002D)
    EnDash character (U+2013)
    EmDash character (U+2014)
    Horizontal bar character (U+2015)

cast-expression:
    type-literal unary-expression

dashdash:
    dash dash

7.2.1 一元逗号运算符

描述:

逗号运算符(,)创建具有一个元素的不受约束的 1 维数组,其类型和值是 一元表达式

此运算符是右结合运算符。

例子:

$a = ,10         # create an unconstrained array of 1 element, $a[0],
                 # which has type int

$a = ,(10,"red") # create an unconstrained array of 1 element,
$a[0],
                 # which is an unconstrained array of 2 elements,
                 # $a[0][0] an int, and $a[0][1] a string

$a = ,,10        # create an unconstrained array of 1 element, which is
                 # an unconstrained array of 1 element, which is an int
                 # $a[0][0] is the int. Contrast this with @(@(10))

7.2.2 逻辑“非”

语法:

logical-not-operator:
    dash not

dash: one of
    - (U+002D)
    EnDash character (U+2013)
    EmDash character (U+2014)
    Horizontal bar character (U+2015)

描述:

运算符 -not 根据需要将 一元表达式 指定的值转换为 bool 类型(§6.2),并生成该类型的结果。 如果 一元表达式值为 True,则结果为 False,反之亦然。 运算符 !-not的另一种拼写方式。

此运算符是右结合运算符。

例子:

-not $true         # False
-not -not $false   # False
-not 0             # True
-not 1.23          # False
!"xyz"             # False

7.2.3 位“非”

语法:

bitwise-not-operator:
    dash bnot

dash: one of
    - (U+002D)
    EnDash character (U+2013)
    EmDash character (U+2014)
    Horizontal bar character (U+2015)

描述:

运算符 -bnot 根据需要将 一元表达式 指定的值转换为整数类型(§6.4)。 如果转换后的值可以在 int int 类型中表示,则为结果类型。 否则,如果转换后的值可以在 类型中表示,则为结果类型。 否则,表达式格式不正确。 结果值为转换后的值的补数。

此运算符是右结合运算符。

例子:

-bnot $true         # int with value 0xFFFFFFFE
-bnot 10            # int with value 0xFFFFFFF5
-bnot 2147483648.1  # long with value 0xFFFFFFFF7FFFFFFF
-bnot $null         # int with value 0xFFFFFFFF
-bnot "0xabc"       # int with value 0xFFFFF543

7.2.4 一元加

描述:

形式为 + unary-expression 的表达式被视为写为 0 + unary-expression (§7.7)。 整数文本 0 具有类型 int

此运算符是右结合运算符。

例子:

+123L         # type long, value 123
+0.12340D     # type decimal, value 0.12340
+"0xabc"      # type int, value 2748

7.2.5 一元减

描述:

形式为 - unary-expression 的表达式被视为写为 0 - unary-expression (§7.7)。 整数文本 0 具有类型 int。 减号运算符可以是 §7.2中列出的 短划线 字符之一。

此运算符是右结合运算符。

例子:

-$true     # type int, value -1
-123L      # type long, value -123
-0.12340D  # type decimal, value -0.12340

7.2.6 前缀增量和减量运算符

描述:

unary-expression 必须指定一个值为数值类型 (§4) 或值 $null 的可写位置。 如果由其 一元表达式 指定的值为 $null,则 一元表达式的值将被转换为 int 类型,并在运算符被计算之前被赋值为零。

备注

一元表达式 指定的值的类型在存储结果时可能会更改。 关于通过赋值进行类型更改的讨论,请参阅 §7.11

对于前缀递增运算符 ++一元表达式的值按相应类型的 1 递增。 增量操作后的新值就是结果。 表达式 ++E 等效于 E += 1§7.11.2)。

对于前缀递减运算符 --一元表达式的值按相应类型的 1 递减。 结果是递减后的新值。 表达式 --E 等效于 E -= 1§7.11.2)。 前缀递减运算符可以是与 §7.2 中的 dashdash 模式匹配的任何模式。

这些运算符是右结合运算符。

例子:

$i = 0                # $i = 0
++$i                  # $i is incremented by 1
$j = --$i             # $i is decremented then $j takes on the value of $i

$a = 1,2,3
$b = 9,8,7
$i = 0;
$j = 1
$b[--$j] = $a[++$i]   # $j is # decremented, $i incremented, then $b[0]
                      # takes on the value of $a[1]

$i = 2147483647       # $i holds a value of type int
++$i                  # $i now holds a value of type double because
                      # 2147483648 is too big to fit in type int

[int]$k = 0           # $k is constrained to int
$k = [int]::MinValue  # $k is set to -2147483648
--$k                  # -2147483649 is too small to fit, imp-def behavior

$x = $null            # target is unconstrained, $null goes to [int]0
--$x                  # value treated as int, 0 becomes -1

7.2.7 一元 -join 运算符

语法:

join-operator:
    dash join

dash: one of
    - (U+002D)
    EnDash character (U+2013)
    EmDash character (U+2014)
    Horizontal bar character (U+2015)

描述:

一元 运算符生成一个字符串,该字符串是由一元表达式指定的一个或多个对象的值的串联。 (可以使用此运算符的二进制版本插入分隔符(§7.8.4.4)。)

一元表达式 可以是标量值或集合。

例子:

-join (10, 20, 30)             # result is "102030"
-join (123, $false, 19.34e17)  # result is "123False1.934E+18"
-join 12345                    # result is "12345"
-join $null                    # result is ""

7.2.8 一元 -split 运算符

语法:

split-operator:
    dash split

dash: one of
    - (U+002D)
    EnDash character (U+2013)
    EmDash character (U+2014)
    Horizontal bar character (U+2015)

描述:

一元 -split 运算符拆分由 一元表达式指定的一个或多个字符串,并在一个受约束的 1 维字符串数组中返回其子部分。 它将任何连续的空格字符组视为连续子部分之间的分隔符。 可以使用此运算符的二进制版本(§7.8.4.5) 或其两个变体(§7.8)来指定显式分隔符字符串。

生成的字符串中不包含分隔符文本。 将忽略输入字符串中的前导空格和尾随空格。 一个为空或包含空格的输入字符串只会导致一个字符串的数组,该数组为空。

一元表达式 可以指定标量值或字符串数组。

例子:

-split " red`tblue`ngreen " # 3 strings: "red", "blue", "green"
-split ("yes no", "up down") # 4 strings: "yes", "no", "up", "down"
-split " " # 1 (empty) string

7.2.9 强制转换运算符

描述:

此运算符将显式 (§6) 将由 unary-expression 指定的值转换为由 type-literal (§7.1.10) 指定的类型。 如果 type-literal 不是 void,则结果的类型为命名类型,并且该值是转换后的值。 如果 type-literal 为 void,则不会将对象写入管道,并且没有结果。

当任何类型的表达式被强制转换为同一类型时,产生的类型和值是 unary-expression 的类型和值。

此运算符是右结合运算符。

例子:

[bool]-10        # a bool with value True
[int]-10.70D     # a decimal with value -10
[int]10.7        # an int with value 11
[long]"+2.3e+3"  # a long with value 2300
[char[]]"Hello"  # an array of 5 char with values H, e, l, l, and o.

7.3 二进制逗号运算符

语法:

array-literal-expression:
    unary-expression , new-lines~opt~ array-literal-expression

描述:

二进制逗号运算符创建了一个一维数组,其元素是由操作数指定的值,并按词法顺序排列。 数组具有不受约束的类型。

例子:

2,4,6                    # Length 3; values 2,4,6
(2,4),6                  # Length 2; values [object[]],int
(2,4,6),12,(2..4)        # Length 3; [object[]],int,[object[]]
2,4,6,"red",$null,$true  # Length 6

向某些二进制逗号表达式添加分组括号不会记录默认优先级;而是更改结果。

7.4 范围运算符

语法:

range-expression:
    unary-expression .. new-lines~opt~ unary-expression

描述:

范围表达式 创建一个不受约束的 1 维数组,其元素是区域边界指定的 int 序列的值。 操作数指定的值将根据需要转换为 int§6.4)。 转换后指定较低值的操作数是 下限,而转换后指定较高值的操作数是 上限。 这两个边界可能相同,在这种情况下,生成的数组具有长度 1。 如果左操作数指定下限,则序列按升序排列。 如果左操作数指定上限,则序列按降序排列。

从概念上讲,此运算符是相应的二进制逗号运算符序列的快捷方式。 例如,也可以使用 5,6,7,8 生成范围 5..8。 但是,如果需要升序或降序序列而不具有数组,则实现可能会避免生成实际数组。 例如,在 foreach ($i in 1..5) { ... }中,无需创建数组。

范围表达式 可用于指定数组切片(§9.9)。

例子:

1..10        # ascending range 1..10
-495..-500   # descending range -495..-500
16..16       # sequence of 1

$x = 1.5
$x..5.40D    # ascending range 2..5

$true..3     # ascending range 1..3
-2..$null    # ascending range -2..0
0xf..0xa     # descending range 15..10

7.5 格式运算符

语法:

format-expression:
    format-specification-string format-operator new-lines~opt~ range-expression

format-operator:
    dash f

dash:
    - (U+002D)
    EnDash character (U+2013)
    EmDash character (U+2014)
    Horizontal bar character (U+2015)

描述:

format-expression 根据 format-expression 指定的 format-specification-string,格式化 range-expression 指定的一个或多个值。 范围表达式 指定的值的位置从零开始编号,以词法顺序递增。 结果具有类型 string

格式说明字符串可能包含零个或多个格式说明,每个格式说明具有以下形式:

{N [ ,M ][ : FormatString ]}

N 表示 范围表达式 值位置,M 表示(可选)最小显示宽度,FormatString 表示 (可选) 格式。 如果格式化值的宽度超过指定的宽度,则会相应地增加宽度。 在计算出任何副作用后,会忽略其位置未在 FormatString 中引用的值。 如果 N 引用不存在的位置,则行为由实现决定。 类型为 $null 和 void 的值的格式为空字符串。 数组被格式化为 子表达式§7.1.6)。 若要在格式规范中包括字符 {},而不将其解释为格式分隔符,请分别将其写入 {{}}

若需格式规范的完整定义,请参阅 Ecma 技术报告 TR/84中的类型 System.IFormattable

例子:

"__{0,3}__" -f 5                         # __ 5__
"__{0,-3}__" -f 5                        # __5 __
"__{0,3:000}__" -f 5                     # __005__
"__{0,5:0.00}__" -f 5.0                  # __ 5.00__
"__{0:C}__" -f 1234567.888               # __$1,234,567.89__
"__{0:C}__" -f -1234.56                  # __($1,234.56)__
"__{0,12:e2}__" -f 123.456e2             # __ 1.23e+004__
"__{0,-12:p}__" -f -0.252                # __-25.20 % __

$i = 5; $j = 3
"__{0} + {1} <= {2}__" -f $i,$j,($i+$j)  # __5 + 3 <= 8__

$format = "__0x{0:X8}__"
$format -f 65535                         # __0x0000FFFF__

在格式规范中,如果 N 引用不存在的位置,则会引发 FormatError

7.6 乘法运算符

语法:

multiplicative-expression:
    multiplicative-expression * new-lines~opt~ format-expression
    multiplicative-expression / new-lines~opt~ format-expression
    multiplicative-expression % new-lines~opt~ format-expression

7.6.1 乘法

描述:

乘法运算符 * 的结果是应用了常规算术转换(§6.15)后两个操作数指定的值的乘积。

此运算符是左结合运算符。

例子:

12 * -10L      # long result -120
-10.300D * 12  # decimal result -123.600
10.6 * 12      # double result 127.2
12 * "0xabc"   # int result 32976

7.6.2 字符串复制

描述:

当左操作数指定一个字符串时,二进制 * 运算符将创建一个新字符串,该字符串由左操作数指定的字符串组成,并根据右操作数的值转换为整数类型后的次数进行复制(§6.4)。

此运算符是左结合运算符。

例子:

"red" * "3"       # string replicated 3 times
"red" * 4         # string replicated 4 times
"red" * 0         # results in an empty string
"red" * 2.3450D   # string replicated twice
"red" * 2.7       # string replicated 3 times

7.6.3 数组复制

描述:

当左操作数指定的是一个数组时,二进制 * 运算符将创建一个新的不受约束的一维数组,其中包含左操作数指定的值复制右操作数指定的次数,转换为整数类型 (§6.4)。 复制次数为零会产生一个长度为 1 的数组。 如果左操作数指定了一个多维数组,则在使用前会将其平展 (§9.12)。

此运算符是左结合运算符。

例子:

$a = [int[]](10,20)              # [int[]], Length 2*1
$a * "3"                         # [object[]], Length 2*3
$a * 4                           # [object[]], Length 2*4
$a * 0                           # [object[]], Length 2*0
$a * 2.3450D                     # [object[]], Length 2*2
$a * 2.7                         # [object[]], Length 2*3
(New-Object 'float[,]' 2,3) * 2  # [object[]], Length 2*2

7.6.4 除法

描述:

除法运算符 / 的结果是在应用常规算术转换 (§6.15) 后,左操作数指定的值除以右操作数指定的值时的商。

如果尝试按零执行整数或十进制除法,则会引发实现定义的终止错误。

此运算符是左结合运算符。

例子:

10/-10      # int result -1
12/-10      # double result -1.2
12/-10D     # decimal result 1.2
12/10.6     # double result 1.13207547169811
12/"0xabc"  # double result 0.00436681222707424

如果尝试按零执行整数或十进制除法,则会引发 RuntimeException 异常。

7.6.5 余数

描述:

余数运算符%的结果是在对左操作数指定的值进行常规算术转换后,将其除以右操作数指定的值(§6.15)所得的余数。

如果尝试按零执行整数或十进制除法,则会引发实现定义的终止错误。

例子:

10 % 3          # int result 1
10.0 % 0.3      # double result 0.1
10.00D % "0x4"  # decimal result 2.00

如果尝试按零执行整数或十进制除法,则会引发 RuntimeException 异常。

7.7 加法运算符

语法:

additive-expression:
    primary-expression + new-lines~opt~ expression
    primary-expression dash new-lines~opt~ expression

dash: one of
    - (U+002D)
    EnDash character (U+2013)
    EmDash character (U+2014)
    Horizontal bar character (U+2015)

7.7.1 加法

描述:

加法运算符 + 的结果是应用了常规算术转换(§6.15)后两个操作数指定的值之和。

此运算符是左结合运算符。

例子:

12 + -10L       # long result 2
-10.300D + 12   # decimal result 1.700
10.6 + 12       # double result 22.6
12 + "0xabc"    # int result 2760

7.7.2 字符串串联

描述:

当左操作数指定了一个字符串时,二进制 + 运算符将创建一个新字符串,其中包含左操作数指定的值,紧接着是右操作数指定的值(将其转换为字符串类型)(§6.8)。

此运算符是左结合运算符。

例子:

"red" + "blue"      # "redblue"
"red" + "123"       # "red123"
"red" + 123         # "red123"
"red" + 123.456e+5  # "red12345600"
"red" + (20,30,40)  # "red20 30 40"

7.7.3 数组连接

描述:

当左操作数指定一个数组时,二进制 + 运算符会创建一个新的不受约束的 1 维数组,其中包含左操作数指定的元素,紧接其后的是右操作数指定的一个或多个值。 任何操作数中存在的多维数组在使用前都会被平展 (§9.12)。

此运算符是左结合运算符。

例子:

$a = [int[]](10,20)               # [int[]], Length 2
$a + "red"                        # [object[]], Length 3
$a + 12.5,$true                   # [object[]], Length 4
$a + (New-Object 'float[,]' 2,3)  # [object[]], Length 8
(New-Object 'float[,]' 2,3) + $a  # [object[]], Length 8

7.7.4 哈希表串联

描述:

当两个操作数都表示哈希表时,二进制 + 运算符会创建一个新的哈希表,其中包含由左操作数表示的元素,紧接着是由右操作数表示的元素。

如果哈希表包含相同的键,则会引发实现定义的终止错误。

此运算符是左结合运算符。

例子:

$h1 = @{ FirstName = "James"; LastName = "Anderson" }
$h2 = @{ Dept = "Personnel" }
$h3 = $h1 + $h2      # new Hashtable, Count = 3

如果哈希表包含相同的键,则会引发 BadOperatorArgument 类型的异常。

7.7.5 减法

描述:

减法运算符 - 的结果是,在应用常规算术转换(§6.15)后,由左操作数指定的值减去右操作数指定的值所得到的差。 减法运算符可以是 §7.7中列出的 短划线 字符之一。

此运算符是左结合运算符。

例子:

12 - -10L      # long result 22
-10.300D - 12  # decimal result -22.300
10.6 - 12      # double result -1.4
12 - "0xabc"   # int result -2736

7.8 比较运算符

语法:

comparison-expression:
    primary-expression comparison-operator new-lines~opt~ expression

comparison-operator:
    equality-operator
    relational-operator
    containment-operator
    type-operator
    like-operator
    match-operator

描述:

左操作数所指定的值的类型决定了在进行比较之前,右操作数所指定的值是否需要转换(§6)。

一些比较运算符有两个变体,一个区分大小写(-c<operator>),一个不区分大小写(-i<operator>)。 -<operator> 版本等效于 -i<operator>。 区分大小写只有在比较字符串类型的值时才有意义。 在非字符串比较上下文中,两个变体的行为相同。

这些运算符是左结合运算符。

7.8.1 相等运算符和关系运算符

语法:

equality-operator: one of
    dash eq     dash ceq    dash ieq
    dash ne     dash cne    dash ine

dash:
    - (U+002D)
    EnDash character (U+2013)
    EmDash character (U+2014)
    Horizontal bar character (U+2015)

relational-operator: one of
    dash lt     dash clt    dash ilt
    dash le     dash cle    dash ile
    dash gt     dash cgt    dash igt
    dash ge     dash cge    dash ige

描述:

有两个相等运算符:相等性(-eq)和不平等(-ne):和四个关系运算符:小于(-lt)、小于或等于(-le)、大于(-gt)和大于或等于(-ge)。 每个都有两个版本(§7.8)。

要使两个字符串相等,它们必须长度相同、内容一致,并且大小写相同(如果适用)。

如果左操作数指定的值不是集合,则结果的类型 bool。 否则,结果可能是一个空的无约束一维数组,其中包含与右操作数指定的值相比测试为 True 的集合元素。

例子:

10 -eq "010"           # True, int comparison
"010" -eq 10           # False, string comparison
"RED" -eq "Red"        # True, case-insensitive comparison
"RED" -ceq "Red"       # False, case-sensitive comparison
"ab" -lt "abc"         # True

10,20,30,20,10 -ne 20  # 10,30,10, Length 3
10,20,30,20,10 -eq 40  # Length 0
10,20,30,20,10 -ne 40  # 10,20,30,20,10, Length 5
10,20,30,20,10 -gt 25  # 30, Length 1
0,1,30 -ne $true       # 0,30, Length 2
0,"00" -eq "0"         # 0 (int), Length 1

7.8.2 包含运算符

语法:

containment-operator: one of
    dash contains       dash ccontains      dash icontains
    dash notcontains    dash cnotcontains   dash inotcontains
    dash in             dash cin            dash iin
    dash notin          dash cnotin         dash inotin

dash:
    - (U+002D)
    EnDash character (U+2013)
    EmDash character (U+2014)
    Horizontal bar character (U+2015)

描述:

包含操作符有四种:包含 (-contains)、不包含 (-notcontains)、属于 (-in) 和不属于 (-notin)。 每个都有两个变体(§7.8)。

包含运算符返回一个布尔值,指示某个值是否至少在数组的元素中出现过一次(或根本没有出现)。 使用 -contains-notcontains时,该值由右操作数指定,数组由左操作数指定。 使用 -in 和 -notin 时,操作数将反转。 该值由左操作数指定,数组由右操作数指定。

出于这些运算符的目的,如果数组操作数具有标量值,则标量值被视为一个元素的数组。

例子:

10,20,30,20,10 -contains 20     # True
10,20,30,20,10 -contains 42.9   # False
10,20,30 -contains "10"         # True
"10",20,30 -contains 10         # True
"010",20,30 -contains 10        # False
10,20,30,20,10 -notcontains 15  # True
"Red",20,30 -ccontains "RED"    # False

7.8.3 类型测试和转换运算符

语法:

type-operator: one of
    dash is
    dash as

dash:
    - (U+002D)
    EnDash character (U+2013)
    EmDash character (U+2014)
    Horizontal bar character (U+2015)

描述:

类型运算符 -is 用于测试左操作数指定的值是否具有由右操作数指定的类型,或是否从这种类型派生。 右操作数必须指定一个类型或一个可以转换为类型的值(例如,命名类型的字符串)。 结果的类型为 bool。 类型运算符 -isnot 返回相应 -is 表达式的逻辑否定。

类型运算符 -as 尝试将左操作数指定的值转换为右操作数指定的类型。 右操作数必须表示一个类型或一个可以转换为类型的值(例如,命名类型的字符串)。 如果转换失败,则返回 $null;否则,将返回转换后的值,并且该结果的返回类型是已转换值的运行时类型。

例子:

$a = 10            # value 10 has type int
$a -is [int]       # True

$t = [int]
$a -isnot $t       # False
$a -is "int"       # True
$a -isnot [double] # True

$x = [int[]](10,20)
$x -is [int[]]     # True

$a = "abcd"        # string is derived from object
$a -is [object]    # True

$x = [double]
foreach ($t in [int],$x,[decimal],"string") {
    $b = (10.60D -as $t) * 2  # results in int 22, double 21.2
}                             # decimal 21.20, and string "10.6010.60"

7.8.4 模式匹配和文本操作运算符

7.8.4.1 -like 和 -notlike 运算符

语法:

like-operator: one of
    dash like       dash clike      dash ilike
    dash notlike    dash cnotlike   dash inotlike

dash:
    - (U+002D)
    EnDash character (U+2013)
    EmDash character (U+2014)
    Horizontal bar character (U+2015)

描述:

如果左操作数未指定集合,则结果具有类型 bool。 否则,结果可能是一个空的无约束一维数组,其中包含与右操作数指定的值相比测试为 True 的集合元素。 右操作数可以指定包含通配符表达式的字符串 (§3.15)。 这些运算符有两个变体(§7.8)。

例子:

"Hello" -like "h*"                   # True, starts with h
"Hello" -clike "h*"                  # False, does not start with lowercase h
"Hello" -like "*l*"                  # True, has an l in it somewhere
"Hello" -like "??l"                  # False, no length match

"-abc" -like "[-xz]*"                # True, - is not a range separator
"#$%\^&" -notlike "*[A-Za-z]"        # True, does not end with alphabetic character
"He" -like "h[aeiou]?*"              # False, need at least 3 characters
"When" -like "*[?]"                  # False, ? is not a wildcard character
"When?" -like "*[?]"                 # True, ? is not a wildcard character

"abc","abbcde","abcgh" -like "abc*"  # object[2], values
"abc" and "abcgh"

7.8.4.2 -match 和 -notmatch 运算符

语法:

match-operator: one of
    dash match      dash cmatch     dash imatch
    dash notmatch   dash cnotmatch  dash inotmatch

dash:
    - (U+002D)
    EnDash character (U+2013)
    EmDash character (U+2014)
    Horizontal bar character (U+2015)

描述:

如果左操作数未指定集合,则结果具有类型 bool;如果结果 $true,则哈希表 $matches 的元素设置为匹配(或不匹配)右操作数指定的值。 否则,结果可能是一个空的无约束一维数组,其中包含与右操作数指定的值相比测试为 True 的集合元素,并且未设置 $matches。 右操作数可能指定一个包含正则表达式的字符串 (§3.16),在这种情况下,它被称为模式。 这些运算符有两个变体(§7.8)。

这些运算符支持子匹配(§7.8.4.6)。

例子:

"Hello" -match ".l"                    # True, $matches key/value is 0/"el"
"Hello" -match '\^h.*o$'               # True, $matches key/value is
0/"Hello"
"Hello" -cmatch '\^h.*o$'              # False, $matches not set
"abc\^ef" -match ".\\\^e"              # True, $matches key/value is 0/"c\^e"

"abc" -notmatch "[A-Za-z]"             # False
"abc" -match "[\^A-Za-z]"              # False
"He" -match "h[aeiou]."                # False, need at least 3 characters
"abc","abbcde","abcgh" -match "abc.*"  # Length is 2, values "abc", "abcgh"

7.8.4.3 -replace 运算符

语法:

binary-replace-operator: one of
    dash replace    dash creplace   dash ireplace

dash:
    - (U+002D)
    EnDash character (U+2013)
    EmDash character (U+2014)
    Horizontal bar character (U+2015)

描述:

-replace 运算符允许使用右操作数指定的值替换左操作数指定的一个或多个字符串中的文本。 此运算符有两个变体(§7.8)。 右操作数具有以下形式之一:

  • 要定位的字符串,它可能包含正则表达式(§3.16)。 在这种情况下,替换字符串为隐式“”。
  • 包含两个对象的数组,第一个对象为要定位的字符串,后一个对象为替换字符串。

如果左侧操作数指定字符串,则结果具有类型字符串。 如果左操作数指定字符串的 1 维数组,则结果是一个不受约束的 1 维数组,其长度与左操作数数组的长度相同,其中包含替换完成后的输入字符串。

此运算符支持子匹配(§7.8.4.6)。

例子:

"Analogous","an apple" -replace "a","*"      # "*n*logous","*n *pple"
"Analogous" -creplace "[aeiou]","?"          # "An?l?g??s"
"Analogous","an apple" -replace '\^a',"%%A"  # "%%Analogous","%%An apple"
"Analogous" -replace "[aeiou]",'$&$&'        # "AAnaaloogoouus"

7.8.4.4 二进制 -join 运算符

语法:

binary-join-operator: one of
    dash join

dash:
    - (U+002D)
    EnDash character (U+2013)
    EmDash character (U+2014)
    Horizontal bar character (U+2015)

描述:

如有必要,二进制 -join 运算符生成一个字符串,该字符串是左操作数指定的一个或多个对象的值在转换为字符串后的连接 (§6.7)。 右操作数指定的字符串用于分隔生成的字符串中的值(可能为空)。

左操作数可以是标量值或集合。

例子:

(10, 20, 30) -join "\|"    # result is "10\|20\|30"
12345 -join ","            # result is "12345", no separator needed
($null,$null) -join "<->"  # result is "<->", two zero-length values

7.8.4.5 二进制 -split 运算符

语法:

binary-split-operator: one of
    dash split      dash csplit     dash isplit

dash:
    - (U+002D)
    EnDash character (U+2013)
    EmDash character (U+2014)
    Horizontal bar character (U+2015)

描述:

二进制 -split 运算符拆分由左操作数指定的一个或多个字符串,并在受约束的字符串数组中返回其子部分。 此运算符有两个变体(§7.8)。 左侧操作数可以指定标量值或字符串数组。 右操作数具有以下形式之一:

  • 分隔符字符串
  • 一个由 2 个对象构成的数组,其中包含一个分隔符字符串,后跟一个数字拆分计数
  • 一个由 3 个对象组成的数组,包含一个分隔符字符串、一个数字拆分计数和一个选项字符串
  • 脚本块
  • 一个由 2 个对象构成的数组,其中包含一个脚本块,后跟一个数字拆分计数

分隔符字符串可能包含正则表达式(§3.16)。 它用于查找包含输入字符串的子部分。 生成的字符串中不包含分隔符。 如果左侧操作数指定空字符串,则会导致空字符串元素。 如果分隔符字符串是空字符串,则会在输入字符串中的每个字符位置找到它。

默认情况下,输入字符串的所有子部分作为单独的元素放入结果中;但是,拆分计数可用于修改此行为。 如果该计数为负数、零或大于或等于输入字符串中的子部分数,则每个子部分将进入一个单独的元素。 如果该计数小于输入字符串中的子部分数,则结果中有计数元素,最后一个元素包含第一个 count - 1 子部分之外的所有子部分。

选项字符串可以包含零个或多个选项名称,每对相邻的选项名称用逗号分隔。 前导、尾随和嵌入的空格将被忽略。 选项名称可以按任意顺序排列,并且区分大小写。

如果选项字符串包含选项名称 SimpleMatch,则它也可能包含选项名称 IgnoreCase。 如果选项字符串包含选项名称 RegexMatch,或者它不包含 RegexMatchSimpleMatch,则它可能包含除 SimpleMatch之外的任何选项名称。 但是,不能同时包含多行单行

下面是选项名称列表:

选项 描述
CultureInvariant 评估分隔符时,忽略语言中的区域性差异。
ExplicitCapture 忽略未命名的匹配组,以便在结果列表中只返回显式捕获组。
IgnoreCase 强制进行不区分大小写的匹配,即使用了 -csplit
IgnorePatternWhitespace 忽略未转义的空格和标记有数字符号 (#) 的注释。
多行 此模式可识别行和字符串的开始和结尾。 默认模式为 单行
RegexMatch 使用正则表达式匹配计算分隔符。 这是默认值。
SimpleMatch 在计算分隔符时使用简单的字符串比较。
单行 此模式仅识别字符串的开始和结尾。 它是默认模式。

脚本块 (§7.1.8) 指定用于确定分隔符的规则,并且必须计算结果为 bool 类型。

例子:

"one,forty two,," -split ","              # 5 strings: "one" "forty two" "" ""

"abc","de" -split ""                      # 9 strings: "" "a" "b" "c" "" "" "d" "e" ""

"ab,cd","1,5,7,8" -split ",", 2           # 4 strings: "ab" "cd" "1" "5,7,8"

"10X20x30" -csplit "X", 0, "SimpleMatch"  # 2 strings: "10" "20x30"

"analogous" -split "[AEIOU]", 0, "RegexMatch, IgnoreCase"
                                          # 6 strings: "" "n" "l" "g" "" "s"

"analogous" -split { $_ -eq "a" -or $_ -eq "o" }, 4
                                          # 4 strings: "" "n" "l" "gous"

7.8.4.6 子匹配项

-match-notmatch-replace 匹配的模式可能包含括号括住的子部分(称为 子匹配)。 请考虑以下示例:

"red" -match "red"

结果是 $true,其中 $matches 的键 0 包含“red”;即左操作数指定的字符串中与右操作数指定模式完全匹配的部分。

在以下示例中,整个模式是一个子匹配。

"red" -match "(red)"

与之前一样,键 0 包含“red”,而键 1 也包含“red”,它是由左操作数指定的与子匹配完全匹配的字符串部分。

请考虑以下更复杂的模式:

"red" -match "((r)e)(d)"

此模式允许“re”、“r”、“d”或“red”的子匹配项。

同样,键 0 包含“红色”。 键 1 包含“re”,键 2 包含“r”,密钥 3 包含“d”。 键/值对在模式中按从左到右的匹配顺序排列,其中较长的字符串匹配优先于较短的字符串匹配。

-replace 的情况下,替换文本可以通过 $n 形式的名称访问子匹配项,其中第一个匹配项是 $1,第二个是 $3,以此类推。 例如,

"Monday morning" -replace '(Monday|Tuesday) (morning|afternoon|evening)','the $2 of $1'

生成的字符串为“星期一上午”。

与其让 $matches 中的键是从零开始的索引,不如使用形式 ?<*name*> 命名子匹配项。 例如,"((r)e)(d)" 可以写入三个命名的子匹配项 m1m2m3,如下所示:"(?<m1>(?<m2>r)e)(?<m3>d)"

7.8.5 移位运算符

语法:

shift-operator: one of
    dash shl
    dash shr

dash:
    - (U+002D)
    EnDash character (U+2013)
    EmDash character (U+2014)
    Horizontal bar character (U+2015)

描述:

左移(-shl)运算符和右移(-shr)运算符将左操作数指定的值转换为整数类型,并在必要时使用常规算术转换(§6.15),将右操作数指定的值转换为 int。

左移位运算符将左操作数向左移动一定数量的位,如下所述计算。 低顺序空位位置设置为零。

右移位运算符将左操作数向右移动一定数量的位,如下所述计算。 左操作数的低顺序位被丢弃,剩余的位向右移位。 当左操作数是有符号值时,如果左操作数为非负操作数,则高阶空位位置设置为零,如果左操作数为负数,则设置为 1。 当左操作数是无符号值时,高阶空位位置设置为零。

当左操作数的类型为 int 时,移位计数由右操作数的低位五位给出。 当右操作数为 long 类型时,移位计数由右操作数的低位六位决定。

例子:

0x0408 -shl 1             # int with value 0x0810
0x0408 -shr 3             # int with value 0x0081
0x100000000 -shr 0xfff81  # long with value 0x80000000

7.9 位运算符

语法:

bitwise-expression:
    unary-expression -band new-lines~opt~ unary-expression
    unary-expression -bor new-lines~opt~ unary-expression
    unary-expression -bxor new-lines~opt~ unary-expression

描述:

按位 AND 运算符 -band、按位 OR 运算符 -bor和按位 XOR 运算符 -bxor 在必要时使用常规算术转换(§6.15)将操作数指定的值转换为整数类型。 转换后,如果两个值都具有类型 int,则为结果的类型。 否则,如果两个值的类型都是 long,则这就是结果的类型。 如果一个值具有类型 int,另一个值具有长类型,则结果的类型为长。 否则,表达式的格式不正确。 结果分别是可能转换的操作数值的按位 AND、按位 OR 或按位 XOR。

这些运算符是左结合运算符。 如果任意一个操作数不包含副作用,则它们是可交换的。

例子:

0x0F0F -band 0xFE    # int with value 0xE
0x0F0F -band 0xFEL   # long with value 0xE
0x0F0F -band 14.6    # long with value 0xF

0x0F0F -bor 0xFE     # int with value 0xFFF
0x0F0F -bor 0xFEL    # long with value 0xFFF
0x0F0F -bor 14.40D   # long with value 0xF0F

0x0F0F -bxor 0xFE    # int with value 0xFF1
0x0F0F -bxor 0xFEL   # long with value 0xFF1
0x0F0F -bxor 14.40D  # long with value 0xF01
0x0F0F -bxor 14.6    # long with value 0xF00

7.10 逻辑运算符

语法:

logical-expression:
    unary-expression -and new-lines~opt~ unary-expression
    unary-expression -or new-lines~opt~ unary-expression
    unary-expression -xor new-lines~opt~ unary-expression

描述:

如有必要,逻辑 AND 运算符 -and 将其操作数指定的值转换为 bool (§6.2)。 结果是可能转换的操作数值的逻辑 AND,类型为 bool。 如果左侧操作数的计算结果为 False,则不计算右操作数。

如有必要,逻辑 OR 运算符 -or 将其操作数指定的值转换为 bool (§6.2)。 结果是可能转换的操作数值的逻辑 OR,类型为 bool。 如果左侧操作数的计算结果为 True,则不计算右操作数。

逻辑 XOR 运算符 -xor 将操作数指定的值转换为 bool§6.2)。 结果是可能转换的操作数值的逻辑 XOR,类型为 bool

这些运算符是左结合运算符。

例子:

$j = 10
$k = 20
($j -gt 5) -and (++$k -lt 15)   # True -and False -> False
($j -gt 5) -and ($k -le 21)     # True -and True -> True
($j++ -gt 5) -and ($j -le 10)   # True -and False -> False
($j -eq 5) -and (++$k -gt 15)   # False -and True -> False

$j = 10
$k = 20
($j++ -gt 5) -or (++$k -lt 15)  # True -or False -> True
($j -eq 10) -or ($k -gt 15)     # False -or True -> True
($j -eq 10) -or (++$k -le 20)   # False -or False -> False

$j = 10
$k = 20
($j++ -gt 5) -xor (++$k -lt 15) # True -xor False -> True
($j -eq 10) -xor ($k -gt 15)    # False -xor True -> True
($j -gt 10) -xor (++$k -le 25)  # True -xor True -> False

7.11 赋值运算符

语法:

assignment-expression:
    expression assignment-operator statement

assignment-operator: *one of
    =   dash =   +=   *=   /=   %=

描述:

赋值运算符将值存储在由 表达式指定的可写位置。 有关 赋值运算符= 的讨论,请参阅 §7.11.1。 有关所有其他赋值运算符的讨论,请参阅 §7.11.2

赋值表达式在赋值进行之后具有由 表达式 指定的值;但是,该赋值表达式本身并不指示一个可写位置。 如果 表达式 是类型约束(§5.3),则在该约束中使用的类型是结果的类型;否则,结果的类型是在应用常规算术转换(§6.15)后的类型。

此运算符是右结合运算符。

7.11.1 简单赋值

描述:

简单赋值=)中,由 语句指定的值 替换由 表达式指定的可写位置中存储的值。 但是,如果 表达式 指定哈希表中不存在的键,该键将添加到哈希表中,该键具有由 语句指定的值的关联值。

如语法所示,表达式 可以指定可写位置的逗号分隔列表。 这称为“多重赋值”语句 指定一个或多个逗号分隔值的列表。 任一操作数列表中的逗号是多赋值语法的一部分,表示二进制逗号运算符。 值取自 语句指定的列表中(按词法顺序),并存储在由 表达式指定的相应可写位置中。 如果由 语句指定的列表 的值少于 表达式 可写位置的值,则多余的位置将采用值 $null。 如果 语句 指定的列表中值的数量超过了 表达式 可写位置的数量,除最右侧的 表达式 位置外,其余位置都将获取相应的 语句 的值。而最右侧的 表达式 位置将变为一个不受约束的一维数组,包含所有剩余的 语句 值作为其元素。

对于具有值的语句(§8.1.2),语句 可以是语句。

例子:

$a = 20; $b = $a + 12L             # $b has type long, value 22
$hypot = [Math]::Sqrt(3*3 + 4*4)   # type double, value 5
$a = $b = $c = 10.20D              # all have type decimal, value 10.20
$a = (10,20,30),(1,2)              # type [object[]], Length 2
[int]$x = 10.6                     # type int, value 11
[long]$x = "0xabc"                 # type long, value 0xabc
$a = [float]                       # value type literal [float]
$i,$j,$k = 10,"red",$true          # $i is 10, $j is "red", $k is True
$i,$j = 10,"red",$true             # $i is 10, $j is [object[]], Length 2
$i,$j = (10,"red"),$true           # $i is [object[]], Length 2, $j is True
$i,$j,$k = 10                      # $i is 10, $j is $null, $k is $null

$h = @{}
[int] $h.Lower, [int] $h.Upper = -split "10 100"

$h1 = @{ FirstName = "James"; LastName = "Anderson"; IDNum = 123 }
$h1.Dept = "Finance"               # adds element Finance
$h1["City"] = "New York"           # adds element City

[int]$Variable:v = 123.456         # v takes on the value 123
${E:output.txt} = "a"              # write text to the given file
$Env:MyPath = "x:\data\file.txt"   # define the environment variable
$Function:F = { param ($a, $b) "Hello there, $a, $b" }
F 10 "red"                         # define and invoke a function
function Demo { "Hi there from inside Demo" }
$Alias:A = "Demo"                  # create alias for function Demo
A                                  # invoke function Demo via the alias

7.11.2 复合赋值

描述:

复合赋值 具有形式 E1 op= E2,并且等效于简单赋值表达式 E1 = E1 op (E2),但复合赋值示例中,表达式 E1 只计算一次。 如果 表达式 是类型约束(§5.3),则在该约束中使用的类型是结果的类型;否则,结果的类型由 op确定。 有关 *=,请参阅 §7.6.1§7.6.2§7.6.3;对于 /=,请参阅 §7.6.4;for %=,请参阅 §7.6.5;对于 +=,请参阅 §7.7.1§7.7.2§7.7.3;有关 -=,请参阅 §7.7.5

注意

当存储结果时,指定数值类型的无约束值的操作数的类型可能会被赋值运算符更改。

例子:

$a = 1234; $a *= (3 + 2)  # type is int, value is 1234 * (3 + 2)
$b = 10,20,30             # $b[1] has type int, value 20
$b[1] /= 6                # $b[1] has type double, value 3.33...

$i = 0
$b = 10,20,30
$b[++$i] += 2             # side effect evaluated only once

[int]$Variable:v = 10     # v takes on the value 10
$Variable:v -= 3          # 3 is subtracted from v

${E:output.txt} = "a"     # write text to the given file
${E:output.txt} += "b"    # append text to the file giving ab
${E:output.txt} *= 4      # replicate ab 4 times giving abababab

7.12 重定向运算符

语法:

pipeline:
    expression redirections~opt~ pipeline-tail~opt~
    command verbatim-command-argument~opt~ pipeline-tail~opt~

redirections:
    redirection
    redirections redirection

redirection:
    merging-redirection-operator
    file-redirection-operator redirected-file-name

redirected-file-name:
    command-argument
    primary-expression

file-redirection-operator: one of
    >   >>   2>   2>>   3>   3>>   4>   4>>
    5>  5>>  6>   6>>   >    >>    <

merging-redirection-operator: one of
    >&1   2>&1   3>&1   4>&1   5>&1   6>&1
    >&2   1>&2   3>&2   4>&2   5>&2   6>&2

描述:

重定向运算符 > 从管道中获取标准输出,并将其重定向到由 redirected-file-name 指定的位置,覆盖该位置的当前内容。

重定向运算符 >> 从管道中获取标准输出,并将其重定向到由 redirected-file-name 指定的位置,附加到该位置的当前内容(如果有的话)。 如果该位置不存在,则会创建它。

形式为 n> 的重定向运算符从管道中获取流 n 的输出,并将其重定向到由 redirected-file-name 指定的位置,覆盖该位置的当前内容。

形式为 n>> 的重定向运算符从管道中获取流 n 的输出,并将其重定向到由 redirected-file-name 指定的位置,附加到该位置的当前内容(如果有的话)。 如果该位置不存在,则会创建它。

包含表单的重定向运算符 m>&n 将流 m 的输出写入到与流 n相同的位置。

以下是有效的流:

Stream 描述
1 标准输出流
2 错误输出流
3 警告输出流
4 详细输出流
5 调试输出流
* 标准输出、错误输出、警告输出、详细输出和调试输出流

重定向运算符 1>&26>6>>< 保留以供将来使用。

如果输出中 重定向文件名 的值为 $null,则输出会被丢弃。

通常,包含顶级副作用的表达式的值不会写入管道,除非该表达式括在一对括号中。 但是,如果此类表达式是重定向标准输出的运算符的左操作数,则写入该值。

例子:

$i = 200                       # pipeline gets nothing
$i                             # pipeline gets result
$i > output1.txt               # result redirected to named file
++$i >> output1.txt            # result appended to named file
type file1.txt 2> error1.txt   # error output redirected to named file
type file2.txt 2>> error1.txt  # error output appended to named file
dir -Verbose 4> verbose1.txt   # verbose output redirected to named file

# Send all output to output2.txt
dir -Verbose -Debug -WarningAction Continue *> output2.txt

# error output redirected to named file, verbose output redirected
# to the same location as error output
dir -Verbose 4>&2 2> error2.txt