powershell -replace,如何只匹配第一个点?

k5hmc34c  于 2023-03-23  发布在  Shell
关注(0)|答案(3)|浏览(369)
$Var = "Dog.Jumping.png", "Horse.Jumping.gif", "Cat.Jumping.jpg", "Lion.Jumping.tiff", "Shark.Jumping.svg", "Cow.Jumping.psd"
$Var -replace '\.', ' - '

上面似乎找到了两个“.”字符,我只对第一个感兴趣。像$Var -replace '\.?', ' - '这样的东西没有意义,我真的被难住了。
任何帮助将不胜感激!

gv8xihay

gv8xihay1#

作为Santiago Squarzon's helpful answer的补充,另一种方法是使用 positive lookbehind assertion。这样的Assert为以下RegEx模式添加了一个要求。它必须以Assert中定义的模式为前导。

$var -replace '(?<=^[^\.]+)\.', ' - '

输出:

Dog - Jumping.png
Horse - Jumping.gif
Cat - Jumping.jpg
Lion - Jumping.tiff
Shark - Jumping.svg
Cow - Jumping.psd

让我们来破译子表达式(?<=^[^\.]+)

  • (?<=启动一个正向后查找Assert
  • ^将以下模式定位到字符串的开头
  • [^\.]+任何不是点的字符,一次或多次(+
  • )结束Assert

Assert的优点是Assert本身不会参与匹配,因此实际上只有点会被替换。
RegEx101 demo

6vl6ewon

6vl6ewon2#

以下内容可能符合您的要求:

$Var -replace '^(.+?)\.', '$1 - '

另一个类似的选择是:

$Var -replace '^([^\.]+)\.', '$1 - '

有关详细信息,请参见https://regex101.com/r/1dhUz2/2
使用Regex的示例提供了一种更简单的方法,因为其中一个.Replace重载具有count参数:

$Var | ForEach-Object { $re = [regex] '\.' } {
    $re.Replace($_, ' - ', 1)
}

但是,作为Olaf noted in his comment,由于这些似乎是有效的文件名,并且假设您已经使用Get-ChildItem收集了它们,您可以在已经排除扩展名的.BaseName ETS属性上使用文字替换。

dzhpxtsq

dzhpxtsq3#

为了提供一个概念上更简单的替代有用的现有答案(这些答案是以regex为中心的):

  • -split操作符允许您通过其可选的第二个操作数限制拆分产生的标记数。
  • -join操作符允许您使用所选分隔符连接生成的标记。

应用于单个字符串:

# -> 'Dog - Jumping.png'
'Dog.Jumping.png' -split '\.', 2  -join ' - '

顺便说一句:split的-很少使用的-可选的 * 第三个 * 操作数支持 * 额外的 * 拆分选项,例如'SimpleMatch'。使用它将导致第一个操作数被解释为 * 文字 * 字符串而不是正则表达式,从而避免了需要转义regex元字符,例如.\
'Dog.Jumping.png' -split '.', 2, 'SimpleMatch' -join ' - '
应用于输入数组:

@(
  "Dog.Jumping.png"
  "Horse.Jumping.gif"
  "Cat.Jumping.jpg"
  "Lion.Jumping.tiff"
  "Shark.Jumping.svg"
  "Cow.Jumping.psd"
) | 
  ForEach-Object {
    $_ -split '\.', 2  -join ' - '
  }

相关问题