字符串介绍
两种类型
PowerShell 下的字符串主要有两种类型:非扩展(nonexpanding)和扩展(expanding)型。
这里的“扩展”和“非扩展”指的是对字符串中包含的变量和转义符是否进行解析。
扩展型字符串需要用双引号括起来,而非扩展型字符串使用单引号。
实际效果如下:1
2
3
4
5
6PS > $username = "starky"
PS > echo "hi, my name is $username. `nAnother line"
hi, my name is starky.
Another line
PS > echo 'hi, my name is $username. `nwithin the same line'
hi, my name is $username. `nwithin the same line
在上面的例子中,双引号包裹的字符串对变量 $username 和转义符 `n(等同于 bash 里的 \n)进行了解析,自动替换为变量和转义符代表的内容。
而单引号包裹的字符串则只是将美元符、反引号等符号视为普通的字符,不做任何处理直接打印输出。
PS:PowerShell 里的转义符是反引号 ` 而不是 bash 里的反斜杠
多行格式化文本
PowerShell 支持创建 here string,即多行格式化文本,类似 Python 里的三引号。只需要将多行文本包裹在成对的 @"
和 "@
符号中即可。示例如下:1
2
3
4
5
6
7
8
9
10
11
12PS > $mystring = @"
>> This is the first line
>> of a very long string. A "here string"
>> lets you create blocks of text
>> that span several lines.
>> "@
>>
PS > $mystring
This is the first line
of a very long string. A "here string"
lets you create blocks of text
that span several lines.
字符串中的动态内容
前面有提到过,由双引号包裹的字符串为“扩展”型字符串,可以对其中包含的变量等自动进行替换。
其实也可以在字符串中,以 $(expression)
的格式插入表达式或一系列 PowerShell 命令,示例如下:1
2PS > "1 + 2 equals $(1 + 2)"
1 + 2 equals 3
还可以使用 PowerShell 的字符串格式化操作符在字符串中插入动态内容,它遵循和 .NET 一样的字符串格式化规则。示例如下:1
2
3
4
5PS > $header = "Report for Today"
PS > $mystring = "{0}`n{1}" -f $header,('-' * $header.Length)
PS > $mystring
Report for Today
----------------
示例 2:1
2
3
4
5
6PS > $number1 = 10
PS > $number2 = 32
PS > "$number2 divided by $number1 is $($number2 / $number1)"
32 divided by 10 is 3.2
PS > "{0} divided by {1} is {2}" -f $number2, $number1, ($number2 / $number1)
32 divided by 10 is 3.2
字符串操作
检索与替换
PowerShell 提供了多种用于字符串搜索和匹配的方法。
-like
-like 操作符用于判断字符串是否匹配特定的模式,该模式中可以包含通配符:1
2PS > "Hello World" -like "*llo W*"
True-match
-match 操作符用于判断字符串是否匹配特定的正则表达式:1
2PS > "Hello World" -match '.*l[l-z]o W.*$'
TrueContains()
Contains() 方法用于判断一个字符串是否包含了另一个较短的字符串:1
2PS > "Hello World".Contains("World")
TrueIndexOf()
IndexOf() 方法可以用来获取一个字符串在另一个字符串中的位置索引:1
2PS > "Hello World".IndexOf("World")
6Replace()
Replace() 方法用于将字符串中的一部分替换为另一个字符串:1
2PS > "Hello World".Replace("World", "PowerShell")
Hello PowerShell
另外,使用 PowerShell 的 -replace
操作符搭配上正则表达式,可以完成更加高级的替换任务:1
2PS > "Hello World" -replace '(.*) (.*)', '$2 $1'
World Hello
分割、合并、修剪
-split
-split 操作符可以用来将指定字符串分割成一系列的字符片段:1
2
3
4
5
6
7
8PS > "a-b-c-d-e-f" -split "-c-"
a-b
d-e-f
PS > "a-b-c-d-e-f" -split "b|[d-e]"
a-
-c-
-
-f-join
-join 操作符用于将多个字符片段合并为一个完整的字符串1
2
3
4
5
6PS > $list = "Hello","World"
PS > $list
Hello
World
PS > $list -join ", "
Hello, WorldTrim()
Trim() 方法用于去除字符串两边的空白字符:1
2
3PS > $text = " `t Test String`t `t"
PS > "|" + $text.Trim() + "|"
|Test String|
列表、数组与哈希表
创建数组和列表
创建和初始化一个数组在 PowerShell 里非常简单,用很常见的赋值语句即可:1
2
3
4
5PS > $myArray = 1,2,"HelloWorld"
PS > $myArray
1
2
HelloWorld
用上述方法创建的数组是没有数据类型限制的,即该数组在初始化时可以包含任何类型的数据。
创建指定长度的数组,可以使用 New-Object
命令:1
2
3
4
5
6
7
8
9
10
11
12
13
14PS > $myArray = New-Object "int32[]" 4
PS > $myArray[3] = 3
PS > $myArray
0
0
0
3
PS > $myArray[4] = 4
索引超出了数组界限。
所在位置 行:1 字符: 1
+ $myArray[4] = 4
+ ~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (:) [], IndexOutOfRangeException
+ FullyQualifiedErrorId : System.IndexOutOfRangeException
创建指定类型的数组,可以使用 .NET 框架提供的强类型的集合:1
2
3
4
5
6
7
8
9
10PS > $list = New-Object Collections.Generic.list[Int]
PS > $list.add(10)
PS > $list.add("Hello")
无法将“Add”的参数“item”(其值为“Hello”)转换为类型“System.Int32”:“无法将值“Hello”转换为类型“System.Int32”。
错误:“输入字符串的格式不正确。””
所在位置 行:1 字符: 1
+ $list.add("Hello")
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
多维数组
PowerShell 可以使用 @()
形式的语法创建多维数组:1
2
3
4
5
6
7
8PS > $jagged = @(
>> (1,2,3,4),
>> (5,6,7,8)
>> )
PS > $jagged[0][0]
1
PS > $jagged[1][3]
8
也可以使用下面的方式:1
2
3
4
5
6
7
8
9
10
11
12PS > $multidimensional = New-Object "int32[,]" 2,4
PS > $multidimensional[0,0] = 1
PS > $multidimensional[1,3] = 8
PS > $multidimensional
1
0
0
0
0
0
0
8
操作数组中的元素
可以通过位置索引(从 0 开始)获取数组中的某个元素:1
2
3
4
5PS > $myArray = 1,2,"Hello World"
PS > $myArray[0]
1
PS > $myArray[2]
Hello World
当然也可以对数组进行分片操作,即获取数组中的某“一段”元素:1
2
3
4
5
6
7PS > $myArray
1
2
Hello World
PS > $myArray[1..2]
2
Hello World
在对数组进行分片时,PowerShell 提供了如下的一个小技巧,可以对输出后的元素进行灵活的排序:1
2
3
4
5
6
7
8PS > $myArray = 0,1,2,3,4,5
PS > $myArray[3..5 + 2 + 0..1]
3
4
5
2
0
1
Foreach-Object
如果需要挨个访问数组中的每一个元素,可以使用 Foreach-Object
命令:1
2
3
4
5PS > $myArray = 1,2,3
PS > $sum = 0
PS > $myArray | Foreach-Object { $sum += $_ }
PS > $sum
6
当然也可以稍微复杂点,通过位置索引和 for
循环访问数组的每一个元素:1
2
3
4
5
6
7PS > $myArray = 1,2,3
PS > $sum = 0
PS > for($i = 0; $i -lt $myArray.Count; $i++) {
>> $sum += $myArray[$i]
>> }
PS > $sum
6
排序
使用 Sort-Object
命令可以对数组元素进行排序后再输出:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21PS > dir
目录: D:\Program\python
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 2019/2/28 22:43 pyqt
d----- 2019/3/3 0:17 speech
-a---- 2019/3/6 22:13 26434 test.html
-a---- 2019/3/6 22:00 174 test.md
PS > Get-ChildItem | Sort-Object -Descending Length | select Name,Length
Name Length
---- ------
test.html 26434
test.md 174
pyqt
speech
使用 Get-ChildItem
获取当前目录下所有文件的列表,再把该列表传递给 Sort-Object
,根据文件占用空间的大小(Length
)逆序输出 Name 和 Length 项。
在使用 Sort-Object 对元素进行排序时,可以自由选择排序依据的条件。如根据首字母对字符串进行排序:1
2
3
4
5PS > "Hello","World","And","Shell" | Sort-Object
And
Hello
Shell
World
根据次字母对字符串进行排序:1
2
3
4
5PS > "Hello","World","And","Shell" | Sort-Object { $_.Substring(1,1) }
Hello
Shell
And
World
数组与运算符
确定数组与元素的包含关系
确定数组与元素的包含关系,可以使用 -contains
或者 -in
操作符:1
2
3
4
5
6
7
8PS > "Hello","World" -contains "Hello"
True
PS > "Hello","World" -contains "Shell"
False
PS > "Hello" -in "Hello","World"
True
PS > "Shell" -in "Hello","World"
False
合并数组
可以使用算术运算符 +
对数组进行合并操作:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16PS > $firstArray = "Element 1","Element 2","Element 3"
PS > $secondArray = 1,2,3
PS > $firstArray + $secondArray
Element 1
Element 2
Element 3
1
2
3
PS > $array = 1,2
PS > $array += 3,4
PS > $array
1
2
3
4
匹配数组中的元素
可以使用 -eq
、-match
、-like
操作符对数组中的元素进行匹配:1
2
3
4
5
6
7
8
9
10PS > $array = "Item 1","Item 2","Item 3","Item 1","Item 12"
PS > $array -eq "Item 1"
Item 1
Item 1
PS > $array -like "*1*"
Item 1
Item 1
Item 12
PS > $array -match "Item .."
Item 12
其中 -eq
表示完全匹配,-like
支持使用通配符,-match
支持正则表达式。
更复杂的匹配条件可以使用 Where-Object
:1
2
3PS > $array = "Item 1","Item 2","Item 3","Item 1","Item 12"
PS > $array | Where-Object { $_.Length -gt 6 }
Item 12
移除数组中的元素
为了移除数组中符合特殊规则的元素,可以使用 -ne
、-notlike
、-notmatch
等比较操作符:1
2
3
4
5
6
7
8
9
10
11
12
13PS >$array = "Item 1","Item 2","Item 3","Item 1","Item 12"
PS >$array -ne "Item 1"
Item 2
Item 3
Item 12
PS > $array -notlike "*1*"
Item 2
Item 3
PS > $array -notmatch "Item .."
Item 1
Item 2
Item 3
Item 1
获取大于或小于特定值的元素
-gt
、-ge
、-lt
、-le
等比较操作符可以用来获取数组中大于或小于某个特定值的元素。
PS:其中 -gt 表示大于(great than),-ge 表示大于等于(great and equal),-lt 表示小于(less than),-le 表示小于等于(less and equal)。1
2
3
4
5
6
7PS > $array = "Item 1","Item 2","Item 3","Item 1","Item 12"
PS > $array -ge "Item 3"
Item 3
PS > $array -lt "Item 2"
Item 1
Item 1
Item 12
ArrayList
通过类似 $array = 1,2,3,4
这种赋值的方式创建的数组,其长度是固定的。
可以通过位置索引访问其中的某个值,并对它重新赋值。但是不能直接添加或者删除数组中的元素:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16PS > $array = 0,1,2,3
PS > $array[1]
1
PS > $array[0]=1
PS > $array
1
1
2
3
PS > $array.Add(4)
使用“1”个参数调用“Add”时发生异常:“集合的大小是固定的。”
所在位置 行:1 字符: 1
+ $array.add(4)
+ ~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : NotSupportedException
如果需要在数组中添加或者删除元素,可以使用 +
、-ne
、-match
、-gt
等比较操作符,获取数组中匹配某个条件的元素,并将它们赋值给新的变量,原数组中元素的值则不受影响:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22PS > $original = 1,2,3,4
PS > $new1 = $original + 5
PS > $new1
1
2
3
4
5
PS > $new2 = $original -ne 4
PS > $new2
1
2
3
PS > $new3 = $original -gt 2
PS > $new3
3
4
PS > $original
1
2
3
4
在面对长度很大的数组时,上述的添加、移除、搜索等操作就会稍微显得效率较低。所以 PowerShell 提供了 ArrayList
数据类型,可以直接对数组本身进行添加、删除等操作:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15PS > $collection = New-Object System.Collections.ArrayList
PS > [void] $collection.Add("Hello")
PS > [void] $collection.AddRange(("World","How","Are","You"))
PS > $collection
Hello
World
How
Are
You
PS > $collection.RemoveAt(1)
PS > $collection
Hello
How
Are
You
[void]
可以省略操作执行后返回的状态值。
哈希表
可以使用 @{}
形式的语法创建哈希表(或关联数组)。1
2
3
4
5
6
7
8
9PS > $myHashtable = @{ Key1 = "Value1"; "Key 2" = 1,2,3 }
PS > $myHashtable["New Item"] = 5
PS > $myHashtable
Name Value
---- -----
Key 2 {1, 2, 3}
Key1 Value1
New Item 5
按哈希表的键或值排序
1 | PS > $myHashtable = @{} |