简体   繁体   English

如何将一系列以连字符分隔的数字分别填充为两位数?

[英]How can I pad a series of hyphen-separated numbers each to two digits?

I am fairly new to PowerShell programming, so need help with set of strings I have as described below:我是 PowerShell 编程的新手,所以需要我的一组字符串的帮助,如下所述:

"14-2-1-1"
"14-2-1-1-1"
"14-2-1-1-10"

I want to pad zero to each number in between - if that number is between 1 and 9 .我想将零填充到中间的每个数字-如果该数字介于19之间。 So the result should look like:所以结果应该是这样的:

"14-02-01-01"
"14-02-01-01-01"
"14-02-01-01-10"

I came up with the following code but was wondering if there is a better/faster solution.我想出了以下代码,但想知道是否有更好/更快的解决方案。

$Filenum = "14-2-1-1"
$hicount = ($Filenum.ToCharArray() | Where-Object{$_ -eq '-'} | Measure-Object).Count
$FileNPad = ''
For ($i=0; $i -le $hicount; $i++) {
    $Filesec= "{$i}" -f $Filenum.split('-')
    If ([int]$Filesec -le 9)
    {
        $FileNPad = "$FileNPad-"+"0"+"$Filesec"
    }
    Else
    {
        $FileNPad="$FileNPad-$Filesec"
    }
}
$FileNPad = $FileNPad.Trim("-"," ")

Instead of trying to manually keep track of how many elements and inspect each value, you can simply split on - , padleft, then join back together with -无需尝试手动跟踪有多少元素并检查每个值,您可以简单地拆分- ,padleft,然后重新加入-

"14-2-1-1","14-2-1-1-1","14-2-1-1-10" | ForEach-Object {
    ($_ -split '-').PadLeft(2,'0') -join '-'
}

Which outputs哪些输出

14-02-01-01
14-02-01-01-01
14-02-01-01-10

I'd be inclined to go with something like Doug Maurer's answer due to its clarity, but here's another way to look at this.由于它的清晰度,我倾向于 go 和类似Doug Maurer 的答案,但这是另一种看待这个问题的方式。 The last section below shows a solution that might be just as clear with some advantages of its own.下面的最后一节显示了一个解决方案,该解决方案可能与它自己的一些优点一样清晰。

Pattern of digit groups in the input输入中数字组的模式

Your input strings are composed of one or more groups, where each group...您的输入字符串由一个或多个组组成,其中每个组...

  1. ...contains one or more digits, and... ...包含一个或多个数字,并且...
  2. ...is preceded by a - or the beginning of the string, and... ...前面有-或字符串的开头,并且...
  3. ...is followed by a - or the end of the string. ...后跟-或字符串的末尾。

Groups that require a leading "0" to be inserted contain exactly one digit;要求插入前导"0"的组恰好包含一个数字; that is, they consist of...也就是说,它们包括...

  1. ...a - or the beginning of the string, followed by... ...a -或字符串的开头,后跟...
  2. ...a single digit, followed by... ...一个数字,然后是...
  3. ...a - or the end of the string. ...a -或字符串的末尾。

Replacing single-digit digit groups using the -replace operator使用-replace运算符替换单个数字组

We can use regular expressions with the -replace operator to locate that pattern and replace the single digit with a "0" followed by that same digit...我们可以使用带有-replace运算符正则表达式来定位该模式,并将单个数字替换为"0" ,后跟相同的数字......

'0-0-0-0', '00-00-00-00', '1-2-3-4', '01-02-03-04', '10-20-30-40', '11-22-33-44' |
    ForEach-Object -Process { $_ -replace '(?<=-|^)(\d)(?=-|$)', '0$1' }

...which outputs... ...哪个输出...

00-00-00-00
00-00-00-00
01-02-03-04
01-02-03-04
10-20-30-40
11-22-33-44

As the documentation describes, the -replace operator is used like this...如文档所述, -replace运算符的用法如下...

<input> -replace <regular-expression>, <substitute>

The match pattern匹配模式

The match pattern '(?<=-|^)(\d)(?=-|$)' means...匹配模式'(?<=-|^)(\d)(?=-|$)'意味着......

The replacement pattern替换模式

The replacement pattern '0$1' means...替换模式'0$1'意味着......

  • The literal text '0' , followed by...文字文本'0' ,后跟......
  • The value of the first capture ( (\d) )第一次捕获的值( (\d)

Replacing single-digit digit groups using [Regex]::Replace() and a replacement [String]使用[Regex]::Replace()和替换[String]替换单个数字组

Instead of the -replace operator you can also call the static Replace() method of the [Regex] class ...除了-replace运算符,您还可以调用[Regex] classstatic Replace()方法...

'0-0-0-0', '00-00-00-00', '1-2-3-4', '01-02-03-04', '10-20-30-40', '11-22-33-44' |
    ForEach-Object -Process { [Regex]::Replace($_, '(?<=-|^)(\d)(?=-|$)', '0$1') }

...and the result is the same. ...结果是一样的。

Replacing digit groups using [Regex]::Replace() and a [MatchEvaluator]使用[Regex]::Replace()[MatchEvaluator]替换数字组

A hybrid of the regular expression and imperative solutions is to call an overload of the Replace() method that takes a [MatchEvaluator] instead of a replacement [String] ...正则表达式和命令式解决方案的混合体是调用Replace()方法的重载,该方法采用[MatchEvaluator]而不是替换[String] ...

# This [ScriptBlock] will be passed to a [System.Text.RegularExpressions.MatchEvaluator] parameter
$matchEvaluator = {
    # The [System.Text.RegularExpressions.Match] parameter
    param($match)

    # The replacement [String]
    return $match.Value.PadLeft(2, '0')
}

'0-0-0-0', '00-00-00-00', '1-2-3-4', '01-02-03-04', '10-20-30-40', '11-22-33-44' |
    ForEach-Object -Process { [Regex]::Replace($_, '(\d+)', $matchEvaluator) }

This produces the same result as above.这会产生与上述相同的结果。

A [MatchEvaluator] is a delegate that takes a Match to be replaced ( $match ) and returns the [String] with which to replace it (the matched text left-padded to two digits). [MatchEvaluator]是一个委托,它接受要替换的Match ( $match ) 并返回用于替换它的[String]匹配的文本左填充到两位数)。 Also note that, whereas above we are capturing only standalone digits (\d) , here we capture all groups of one or more digits (\d+) and leave it to PadLeft() to figure out if a leading "0" is needed.另请注意,虽然上面我们只捕获独立数字(\d) ,但在这里我们捕获所有一个或多个数字组(\d+)并将其留给PadLeft()来确定是否需要前导"0"

I think this is a much more compelling solution than regular expressions alone because it's the best of that and the imperative world:我认为这是一个比单独使用正则表达式更有说服力的解决方案,因为它是正则表达式和命令式世界中最好的:

  • It uses a simple regular expression pattern to locate digit groups in the input string它使用简单的正则表达式模式来定位输入字符串中的数字组
  • It uses a simple [ScriptBlock] to transform digit groups in the input string它使用一个简单的[ScriptBlock]来转换输入字符串中的数字组
  • By not splitting the input string apart it does not create as much intermediate string and arraygarbage通过不将输入字符串分开,它不会产生尽可能多的中间字符串和数组垃圾
    • Whether this potential performance improvement is overshadowed by using regular expressions at all, I can't say without benchmarking这种潜在的性能改进是否完全被使用正则表达式所掩盖,我不能说没有基准测试

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

相关问题 如何将单个数字和连字符之间的数字与string.match匹配? - How to match single digits and digits separated by a hyphen with string.match? 如何将包含“巨大数字”(超过 30 位)的两个字符串相乘? - How can I multiply two strings containing 'huge numbers' (over 30 digits)? 用连字符分隔的文本扩展数字 R - expand numbers with text separated by hyphen R Python - 从字符串中提取由连字符分隔的数字 - Python - Extract Numbers Separated by Hyphen from String 对每个由空格或连字符分隔的字符串执行方法 - Perform method on each string separated by whitespace or hyphen 如何获得用户输入的每个数字作为字符串中的数字集,每个数字之间用空格分隔? - How do I get each number a user inputs as set of numbers in string with each number separated by a space? 如何在 Java 中填充字符串? - How can I pad a String in Java? 如何填充字符串中的所有数字 - How to pad all the numbers in a string 如何在给定数字的左边放置零,最多6个数字(包括给定数字) - How can I place zeroes to the left of a given number to a maximum of 6 digits including the given numbers 如何编写 python 程序来打印用逗号分隔的一串数字的总和? - How can I write a python program to print the sum of a string of numbers that are separated by a comma?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM