提取字符串中文件扩展名 (.ps1) 之前的数字 [英] Extract the number before a file extension (.ps1) in a string

查看:29
本文介绍了提取字符串中文件扩展名 (.ps1) 之前的数字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

创建文件的 cmdlet 返回一个文本块,其中是文件的名称.该文件的格式为string[number].ps1,但数字是随机的,所以我想提取该数字并将其存储在一个变量中.

供参考的文本块:

 + ~~~~~~\n'using' 语句必须出现在\中的任何其他语句之前\ 一个脚本.\n在 C:\\Packages\\Plugins\\Microsoft.CPlat.Core.RunCommandWindows\\\1.1.3\\下载\\script35.ps1:20 char:8\n+ 使用 Microsoft.Build.Framework;\n\+ ~\n缺少 using 指令\nAt C:\\Packages\\Plugins\\Microsoft.CPlat.Core.RunCommandWindows\\\1.1.3\\下载\\script35.ps1:20 char:3\n+ 使用 Microsoft.Build.Framework;\n\+ ~~~~~\n'using' 语句必须出现在\\ 一个脚本.\n在 C:\\Packages\\Plugins\\Microsoft.CPlat.Core.RunCommandWindows\\\1.1.3\\下载\\script35.ps1:21 char:8\n+ 使用 Microsoft.Build.Utilities;\n\+ ~\n缺少 using 指令\nAt C:\\Packages\\Plugins\\Microsoft.CPlat.Core.RunCommandWindows\\\1.1.3\\下载\\script35.ps1:21 char:3\n+ 使用 Microsoft.Build.Utilities;\n\+ ~~~~~\n'using' 语句必须出现在\

我认为 $result -match '\d\d+(?=\.\w+)' 会起作用,但它只返回找到数字的行,而不仅仅是数字.

解决方案

使用 集合(而不是单个值)作为 LHS,-match 运算符::>

  • 充当过滤器 - 即返回匹配元素的子数组,而不是布尔值

  • 是否填充自动$Matches 变量与匹配运算符的结果.

这就是为什么您的输出包含匹配的行作为一个整体.

<小时>

要仅返回匹配的部分,您可以使用 switch 语句-Regex 选项循环遍历您的行数组,在这种情况下 $Matches 为每个输入行填充:

# 示例行数组.# 为了便于说明,我调整了`script.ps1`# 令牌具有连续的数字.$行 = @'+ ~~~~~\n'using' 语句必须出现在\\ 一个脚本.\n在 C:\\Packages\\Plugins\\Microsoft.CPlat.Core.RunCommandWindows\\\1.1.3\\下载\\script35.ps1:20 char:8\n+ 使用 Microsoft.Build.Framework;\n\+ ~\n缺少 using 指令\nAt C:\\Packages\\Plugins\\Microsoft.CPlat.Core.RunCommandWindows\\\1.1.3\\下载\\script36.ps1:20 char:3\n+ 使用 Microsoft.Build.Framework;\n\+ ~~~~~\n'using' 语句必须出现在\\ 一个脚本.\n在 C:\\Packages\\Plugins\\Microsoft.CPlat.Core.RunCommandWindows\\\1.1.3\\下载\\script37.ps1:21 char:8\n+ 使用 Microsoft.Build.Utilities;\n\+ ~\n缺少 using 指令\nAt C:\\Packages\\Plugins\\Microsoft.CPlat.Core.RunCommandWindows\\\1.1.3\\下载\\script38.ps1:21 char:3\n+ 使用 Microsoft.Build.Utilities;\n\+ ~~~~~\n'using' 语句必须出现在\'@ -split '\r?\n'# 逐行执行匹配,# 并输出每一行的匹配部分,# 产生一个字符串数组.# 前置# $结果 =# 将数组存储在变量中.switch -Regex ($lines) {'\d+(?=\.\w+)' { $Matches[0] } # 只提取*1st*匹配,# 追加`;在 { ... } 内中断`}

以上产生:

35363738

请注意,switch 还支持直接从文件中读取行,使用 -File 选项
(switch -Regex -File $filePath { ... }).

A cmdlet that creates a file returns a block of text, and in that is the name of the file. The file has a format of string[number].ps1, but the number is random, so I would like to extract that number and store it in a variable.

Block of text for reference:

  +         ~~~~~\nA 'using' statement must appear before any other statements in\
    \ a script.\nAt C:\\Packages\\Plugins\\Microsoft.CPlat.Core.RunCommandWindows\\\
    1.1.3\\Downloads\\script35.ps1:20 char:8\n+         using Microsoft.Build.Framework;\n\
    +              ~\nMissing using directive\nAt C:\\Packages\\Plugins\\Microsoft.CPlat.Core.RunCommandWindows\\\
    1.1.3\\Downloads\\script35.ps1:20 char:3\n+         using Microsoft.Build.Framework;\n\
    +         ~~~~~\nA 'using' statement must appear before any other statements in\
    \ a script.\nAt C:\\Packages\\Plugins\\Microsoft.CPlat.Core.RunCommandWindows\\\
    1.1.3\\Downloads\\script35.ps1:21 char:8\n+         using Microsoft.Build.Utilities;\n\
    +              ~\nMissing using directive\nAt C:\\Packages\\Plugins\\Microsoft.CPlat.Core.RunCommandWindows\\\
    1.1.3\\Downloads\\script35.ps1:21 char:3\n+         using Microsoft.Build.Utilities;\n\
    +         ~~~~~\nA 'using' statement must appear before any other statements in\

I thought $result -match '\d\d+(?=\.\w+)' would work, but it only returned the lines the number was found on, instead of just the number.

解决方案

With a collection (as opposed to a single value) as the LHS, the -match operator:

  • acts as a filter - i.e. returns the subarray of matching elements rather than a Boolean

  • does not populate the automatic $Matches variable with the matching operator's results.

That's why your output comprised the matching lines as a whole.


To return only the matching parts, you can use a switch statement with the -Regex option to loop over your array of lines, in which case $Matches is populated for each input line:

# Array of sample lines.
# For illustrative purposes I've tweaked the `script<number>.ps1`
# tokens to have successive numbers.
$lines = @'
 +         ~~~~~\nA 'using' statement must appear before any other statements in\
    \ a script.\nAt C:\\Packages\\Plugins\\Microsoft.CPlat.Core.RunCommandWindows\\\
    1.1.3\\Downloads\\script35.ps1:20 char:8\n+         using Microsoft.Build.Framework;\n\
    +              ~\nMissing using directive\nAt C:\\Packages\\Plugins\\Microsoft.CPlat.Core.RunCommandWindows\\\
    1.1.3\\Downloads\\script36.ps1:20 char:3\n+         using Microsoft.Build.Framework;\n\
    +         ~~~~~\nA 'using' statement must appear before any other statements in\
    \ a script.\nAt C:\\Packages\\Plugins\\Microsoft.CPlat.Core.RunCommandWindows\\\
    1.1.3\\Downloads\\script37.ps1:21 char:8\n+         using Microsoft.Build.Utilities;\n\
    +              ~\nMissing using directive\nAt C:\\Packages\\Plugins\\Microsoft.CPlat.Core.RunCommandWindows\\\
    1.1.3\\Downloads\\script38.ps1:21 char:3\n+         using Microsoft.Build.Utilities;\n\
    +         ~~~~~\nA 'using' statement must appear before any other statements in\
'@ -split '\r?\n'

# Perform the matching, line by line,
# and output each line's matching part,
# resulting in an array of strings.
# Prepend 
#     $result = 
# to store the array in a variable.
switch -Regex ($lines) {
  '\d+(?=\.\w+)' { $Matches[0] } # to extract only the *1st* match,
                                   # append `; break` inside the { ... }
}

The above yields:

35
36
37
38

Note that switch also supports reading lines directly from a file, using the -File option
(switch -Regex -File $filePath { ... }).

这篇关于提取字符串中文件扩展名 (.ps1) 之前的数字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆