使用Powershell中的函数替换

时间:2015-06-05 12:03:24

标签: regex powershell

我正在尝试替换Powershell中的部分字符串。但是,替换字符串不是硬编码的,而是根据函数计算的:

$text = "the image is -12345-"
$text = $text -replace "-(\d*)-", 'This is the image: $1'
Write-Host $text

这给了我正确的结果:     “这是图像:12345”

现在,我想要包含base64编码的图像。我可以从id读取图像。我希望以下内容能够奏效,但事实并非如此:

function Get-Base64($path)
{
    [convert]::ToBase64String((get-content $path -encoding byte))
}
$text -replace "-(\d*)-", "This is the image: $(Get-Base64 '$1')"

它不起作用的原因是因为它首先将$1(字符串,而不是$1的值)传递给函数,执行它然后才进行替换。我想做的是

  • 查找模式的出现次数
  • 用模式
  • 替换每个出现的情况
  • 每次更换:
  • 将捕获组传递给函数
  • 使用捕获组的值获取base64图像
  • 将base64图像注入替换

3 个答案:

答案 0 :(得分:14)

您可以使用[regex]类中的静态Replace方法:

[regex]::Replace($text,'-(\d*)-',{param($match) "This is the image: $(Get-Base64 $match.Groups[1].Value)"})

或者,您可以定义regex对象并使用该对象的Replace方法:

$re = [regex]'-(\d*)-'
$re.Replace($text, {param($match) "This is the image: $(Get-Base64 $match.Groups[1].Value)"})

为了更好的可读性,您可以在单独的变量中定义回调函数(scriptblock)并在替换中使用它:

$callback = {
  param($match)
  'This is the image: ' + (Get-Base64 $match.Groups[1].Value)
}

$re = [regex]'-(\d*)-'
$re.Replace($text, $callback)

答案 1 :(得分:4)

从v5.1开始,

PetSerAl's helpful answer Windows PowerShell 中的唯一选项。

PowerShell Core v6.1 +现在通过增强对
的功能提供了本机PowerShell解决方案。 -replace运算符
,从而无需调用[regex]::Replace()

[regex]::Replace()一样,您现在可以:

  • 传递 script块作为-replace替换操作数,该操作数必须返回替换字符串,
  • 除了当前匹配项(类型为[System.Text.RegularExpressions.Match]的匹配项)表示为自动变量$_(按照PowerShell中的惯例)之外。

适用于您的情况:

$text -replace "-(\d*)-", { "This is the image: $(Get-Base64 $_.Groups[1].Value)" }

一个简单的例子:

# Increment the number embedded in a string:
PS> '42 years old' -replace '\d+', { [int] $_.Value + 1 }
43 years old

答案 2 :(得分:0)

这是另一种方式。使用-match运算符,然后引用$ matches。请注意,$ matches不会在-match运算符左侧设置数组。 $ matches.1是()组成的第一个分组。

$text = "the image is -12345-"
function Get-Base64($path) { 
  [convert]::ToBase64String( (get-content $path -asbytestream) ) }  # ps 6 ver
if (! (test-path 12345)) { echo hi > 12345 }
$text -match '-(\d*)-'
$text -replace '-(\d*)-', "$(Get-Base64 $matches.1)"

the image is aGkNCg==

或进一步分解:

$text -match '-(\d*)-'
$result = Get-Base64 $matches.1
$text -replace '-(\d*)-', $result