简体   繁体   English

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

[英]Sort an array numerically by extracting integers in names

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

I get the output我得到 output

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
...

$Folders = $Folders | $文件夹 = $文件夹 | Sort-Object {[INT]($_ -Replace 'Set ', '')} will sort the names in the right order but doesn't work if there is anything after the number like ' - A Memo'. Sort-Object {[INT]($_ -Replace 'Set ', '')} 将以正确的顺序对名称进行排序,但如果数字后面有任何内容,例如“ - A Memo”,则不起作用。

I've tried \b\d+\b on https://regexr.com but don't know how to implement that in this case.我已经在https://regexr.com上尝试了 \b\d+\b 但不知道如何在这种情况下实现它。 I need a regex that can extract the number after 'Set ' and discard everything else.我需要一个正则表达式,它可以在“Set”之后提取数字并丢弃其他所有内容。

RegEx is a whole other language in itself RegEx 本身就是另一种语言

$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.+')}}

You can use an expression with Sort-Object .您可以使用带有Sort-Object的表达式。 Above this is done to replace everything you don't care about and convert to int for number sorting (in text sorting 1, 10, 11, 2, 20... is expected.)这样做是为了替换您不关心的所有内容并转换为int进行数字排序(在文本排序中 1、10、11、2、20 1, 10, 11, 2, 20...是预期的。)

Regex breakdown正则表达式分解

^  - 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

Note: + matches 1 or more.注意: +匹配 1 个或多个。 Use * if you need to match 0 or more.如果您需要匹配 0 个或更多,请使用*

Edit: As per zett42's helpful comment, you could use [int]($_ -split ' ')[1] in the Sort-Object expression.编辑:根据 zett42 的有用评论,您可以在Sort-Object表达式中使用[int]($_ -split ' ')[1] This splits your name into an array, and takes the 2nd element of that array.这会将您的姓名拆分为一个数组,并获取该数组的第二个元素。

Some alternatives for extracting the number, complementing g.sulman 's excellent answer .提取数字的一些替代方法,补充g.sulman的出色答案

First the most simplest method, assuming "Set" and the number are always separated by space:首先是最简单的方法,假设“Set”和数字总是用空格隔开:

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

This uses the -split operator to split the string on space character, which returns an array.这使用-split运算符将字符串拆分为空格字符,从而返回一个数组。 Then it converts the 2nd element to int .然后它将第二个元素转换为int


Use -match operator:使用-match运算符:

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

Note that conditional operator ?注意条件运算符? requires PS 7. Alternative for older PS versions:需要 PS 7。旧 PS 版本的替代方案:

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

The -match operator finds the first sub string that matches the RegEx \d+ which stands for one or more digits. -match运算符查找与代表一个或多个数字的 RegEx \d+匹配的第一个子字符串。 The found sub string can be accessed through $matches[0] .可以通过$matches[0]访问找到的子字符串。


Use Select-String cmdlet:使用Select-String cmdlet:

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

Same principle as the -match method.-match方法的原理相同。 Just a different way to access the found sub string.只是访问找到的子字符串的另一种方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM