通过提取名称中的整数对数组进行数字排序

时间:2021-01-24 20:53:20

标签: arrays powershell sorting

$Folders = Get-ChildItem -LiteralPath $PSScriptRoot | Where-Object {$_.PSIsContainer} | Select-Object -ExpandProperty BaseName

我得到输出

Set 1
Set 10
Set 11 - A Memo
Set 2
Set 20
Set 22 - A Memo With Numbers 1234
Set 3
Set 33 - A Memo
...

$文件夹 = $文件夹 | Sort-Object {[INT]($_ -Replace 'Set ', '')} 将按正确的顺序对名称进行排序,但如果数字后面有类似“-备忘录”之类的内容则不起作用。

我在 https://regexr.com 上尝试过 \b\d+\b 但不知道在这种情况下如何实现。 我需要一个可以提取“Set”之后的数字并丢弃其他所有内容的正则表达式。

RegEx 本身就是另一种语言

2 个答案:

答案 0 :(得分:2)

$names = @"
Set 1
Set 10
Set 11 - A Memo
Set 2
Set 20
Set 22 - A Memo With Numbers 1234
Set 3
Set 33 - A Memo
"@ -split "`n"

$names | sort @{expression={[int]($_ -replace '^\w+\s|\s.+')}}

您可以使用带有 Sort-Object 的表达式。上面这样做是为了替换您不关心的所有内容并转换为 int 进行数字排序(在文本排序中需要 1, 10, 11, 2, 20 ...。)

正则表达式分解

^  - start of the string
\w - word character (matches S)
+  - the previous thing as many times as need (matches Se, Set, Seet, Seeeeeeeet)
\s - space
|  - or. so either everything before this, or everything after
\s - space
.  - any character
+  - I think this one's covered above

注意:+ 匹配 1 个或多个。如果您需要匹配 0 个或多个,请使用 *

编辑:根据 zett42 的有用评论,您可以在 [int]($_ -split ' ')[1] 表达式中使用 Sort-Object。这会将您的姓名拆分为一个数组,并获取该数组的第二个元素。

答案 1 :(得分:2)

提取数字的一些替代方法,补充了 g.sulman 出色的 answer

第一个最简单的方法,假设“Set”和数字总是用空格隔开:

$Folders | Sort-Object { [int]($_ -split ' ')[1] }

这使用 -split 运算符将字符串拆分为空格字符,返回一个数组。然后它将第二个元素转换为 int


使用 -match 运算符:

$Folders | Sort-Object { [int]( $_ -match '\d+' ? $matches[0] : 0 ) }

请注意,条件运算符 ? 需要 PS 7。旧 PS 版本的替代方法:

$Folders | Sort-Object { [int]( if( $_ -match '\d+' ){ $matches[0] } else { 0 } ) }

-match 运算符查找与代表一个或多个数字的 RegEx \d+ 匹配的第一个子字符串。可以通过 $matches[0] 访问找到的子字符串。


使用 Select-String cmdlet:

$Folders | Sort-Object { [int] ( $_ | Select-String -Pattern \d+ ).Matches[0].Value }

原理与 -match 方法相同。只是一种访问找到的子字符串的不同方式。

相关问题