文件名如下
$inpFiledev = "abc_XYZ.bak"
我只需要一个变量中的XYZ即可与其他文件名进行比较。 我在下面尝试过:
[String]$findev = [regex]::match($inpFiledev ,'_*.').Value
Write-Host $findev
答案 0 :(得分:5)
正则表达式中的星号的行为与在文件系统列表命令中的行为不同。就目前而言,您的正则表达式正在寻找下划线,重复零次或多次,后跟任意字符(在正则表达式中以句点表示)。因此,正则表达式会在字符串开头立即找到零个下划线,然后找到“ a”,这就是它返回的匹配项。
首先,更正该位:
'_*.'
成为“下划线,后跟任意数量的字符,后跟文字句号”。 “文学时期”表示我们需要使用\.
来跳过正则表达式中的时期,记住该时期意味着任何字符:
'_.*\.'
_
下划线.*
任意数量的字符\.
文字期间返回:
_XYZ。
所以,距离不远。
如果您希望从字符之间返回某些内容,则需要使用捕获组。在要保留的位上加上括号:
'_(.*)\.'
然后,您将需要使用PowerShell正则表达式组来获取值:
[regex]::match($inpFiledev ,'_(.*)\.').Groups[1].Value
哪个返回:XYZ
Groups [1]中的数字1表示第一个捕获组,可以通过使用更多的括号将任意数量的表达式添加到表达式中,但是在这种情况下,您只需要一个即可。
答案 1 :(得分:4)
用两个PowerShell惯用的替代方法补充mjsqu's helpful answer:
有关在PowerShell中如何使用 regexes (正则表达式)的概述,请参见Get-Help about_regular_expressions
。
使用-split
除以_
和.
,提取所得的3元素数组的中间元素:
PS> ("abc_XYZ.bak" -split '[_.]')[1]
XYZ
-split
的(第一个)RHS操作数是一个正则表达式;正则表达式[_.]
是与单个字符相匹配的字符集([...]
)。 _
因此,输入.
被分成一个包含字符串abc_XYZ.bak
,abc
和XYZ
的数组。因此,应用索引bak
会提取中间令牌[1]
。使用XYZ
通过捕获组(-replace
,在替换操作数中称为(...)
)提取感兴趣的令牌:
$1
PS> "abc_XYZ.bak" -replace '^.+_([^.]+).+$', '$1'
XYZ
也在正则表达式上作为第一个RHS操作数-要替换的内容-而第二个操作数指定了将匹配的(sub)字符串用替换的内容。 / p>
正则表达式-replace
:
^.+_([^.]+).+$
在输入(^.+_
的开头匹配一个或多个(+
)字符(.
)-注意{{1} }-在字符集(^
之外使用-是一个正则表达式元字符,它表示任何字符(在单行输入字符串中)。
.
是一个捕获组([...]
),与取反的字符集(([^.]+)
)相匹配: (...)
匹配任何文字字符。 不是文字[^...]
一次或多次([^.]
)。
无论.
中与子表达式匹配的内容,都可以在替换操作数中引用为+
,其中(...)
表示捕获组中基于1的索引。正则表达式在这种情况下,$<n>
可以用于引用此第一个(也是唯一一个)捕获组。
<n>
匹配一个或多个($1
)个剩余字符(.+$
),直到到达输入结尾(+
)。
替换操作数.
仅指第一个捕获组所匹配的内容。在这种情况下:$
。
$1
替换操作数的语法的全面概述,请参见this answer。答案 2 :(得分:1)
由于您使用的是[regex]
加速器,因此需要反斜杠来结束.
的结尾(如果要匹配它),并且在星号之前需要一个点以匹配任何字符下划线之后。如果两者之间的字符都是字母,请使用\w+
$findev = [regex]::match($inpFiledev ,'_.*\.')
$findev
_XYZ.
答案 3 :(得分:1)
这演示了另外两种从样本字符串中获取所需信息的方法。第一种在原始字符串上使用基本的Object.equals()
字符串方法。第二个假设是您要处理文件对象,首先从获取文件的.Split()
开始。已经删除了扩展名,因此您不必费心去做。
如果您要处理的是大个字符串,而不是文件对象,那么以前的正则表达式答案可能会更快。 [咧嘴]
.BaseName
输出...
$inpFiledev = 'abc_XYZ.bak'
$findev = $inpFiledev.Split('.')[0].Split('_')[-1]
# fake reading in a file with Get-Item or Get-ChildItem
$File = [System.IO.FileInfo]'c:\temp\testing\abc_XYZ.bak'
$WantedPart = $File.BaseName.Split('_')[-1]
'split on a string = {0}' -f $findev
'split on BaseName of file = {0}' -f $WantedPart