0

这里有两个代码块显示了 Leftpad 的奇怪行为。

$array = "z", "fg"
$array -replace "(\w{1,2})", '$1'.PadLeft(2, "0")
# output: z, fg

$array = "z", "fg"
$array -replace "(\w{1,2})", '$1'.PadLeft(3, "0")
# output: 0z, 0fg

焊盘长度怎么不固定?

编辑:@LotPings

我问这个另一个问题是因为你在应用于rename-item语句时这样做的方式不会影响名称中带有括号的文件。

$file_names = ls "G:\Donwloads\Srt Downloads\15" -Filter *.txt
# the files are: "Data Types _ C# _ Tutorial 5.txt", "If Statements (con't) _ C# _ Tutorial 15.txt"
$file_names | 
    ForEach{
        if ($_.basename -match '^([^_]+)_[^\d]+(\d{1,2})$')
            { 
            $file_names | 
                Rename-Item -NewName `
                    { ($_.BaseName -replace $matches[0], ("{0:D2}. {1}" -f [int]$matches[2],$matches[1])) + $_.Extension }
            } 
           }

# output: 05. Data Types.txt
#         If Statements (con't) _ C# _ Tutorial 15.txt

至于.PadLeft,我认为正则表达式替换组是字符串类型的,它应该可以使用,.PadLeft但不能。

4

2 回答 2

2

Ansgars对您最后一个问题的评论应该表明您对行动顺序的假设是错误的。
Lee_Dailey再次证明你错了。

对您上一个问题的回答提出了另一种在这里也适用的方法:

("Data Types _ C# _ Tutorial 5", "If Statements (con't) _ C# _ Tutorial 15") |
  ForEach{ 
    if ($_ -match '^([^_]+)_[^\d]+(\d{1,2})$'){
      "{0:D2}. {1}" -f [int]$matches[2],$matches[1]
    } 
  }

样本输出:

05. Data Types
15. If Statements (con't)

您问题的最后一次编辑实际上是一个新问题......

  • Rename-Item 接受管道输入,因此ForEach-Object在使用时也不需要
  • Where-Object用 -match 运算符替换 if。
    $Matches 集合的提供方式相同。
  • 我真的不知道为什么您在使用 -format 运算符从头开始构建 NewName 时坚持使用 -replace 运算符。

$file_names = Get-ChildItem "G:\Donwloads\Srt Downloads\15" -Filter *.txt

$file_names | Where-Object BaseName -match '^([^_]+)_[^\d]+(\d{1,2})$' |
    Rename-Item -NewName {"{0:D2}. {1}{2}" -f [int]$matches[2],$matches[1].Trim(),$_.Extension} -WhatIf
于 2018-12-31T23:05:25.213 回答
0

问了这个问题几天后,我碰巧找出了问题所在。

语法中的$number捕获组引用-replace仅仅是文字字符串!

Powershell 从不将它们视为任何特殊的东西,但 Regex 引擎却可以。看下面的例子:

$array = "z", "fg"  
$array -replace "(\w{1,2})", '$1'.Length
#output: 2
#        2

看起来很奇怪?捕获组的$1“z”和“fg”的长度为何均为 2?答案是被计算的长度是字符串$1而不是"z","fg"!
让我们看另一个例子,这次让我们替换捕获组中的一个字母,看看会发生什么:

$array -replace "(\w{1,2})", '$1'.Replace("z", "6")
#output: z
#        fg

输出显示.replace不适用于捕获组 1。

$array -replace "(\w{1,2})", '$1'.Replace("1", "6")
#output: $6
#        $6

看?被替换的字符串是$1它自己。
现在.padleft应该了解问题的原因。PS 填充文字字符串$1并使用组的内容显示结果。
当我用 填充它时.Padleft(2, "0"),没有任何反应,因为“$1”本身的长度为 2。

$array -replace "(\w{1,2})", '$1'.PadLeft(2, "0")
# output: z
#         fg

相反,如果我用 填充它.Padleft(3, "0"),这一次 pad 方法确实生效,它会将额外的“0”应用到$1但在 的内容之前显示“0”的结果$1

$array -replace "(\w{1,2})", '$1'.PadLeft(3, "0")
#output: 0z
#        0fg
于 2019-01-04T18:18:41.857 回答