PowerShell函数开发:按序替换URI模板{id}及处理ID追加场景
解决PowerShell模板按顺序替换{id}并处理追加的问题
先明确需求和现有问题:
现有变量:
$list = @("123","456","789") $template = "https://mysite.test/api/v1/policy/{id}/version/{id}/example"
需要实现的逻辑:
- 按数组
$list的顺序,逐个替换模板里的{id} - 如果数组元素数比模板中
{id}的数量多1,把最后一个ID以/ID的形式追加到字符串末尾 - 数组元素数只能等于
{id}数量或者多1,否则报错
现有代码的问题
你当前的代码会把所有{id}都替换成数组第一个元素,因为-replace默认会替换所有匹配项,第一次循环就把模板里的{id}全换成了123,后续循环找不到匹配项,自然没效果:
if ($template.Contains('{id}')) { foreach ($id in $list ) { $template = $template -replace '{id}', $id } } # 错误输出:https://mysite.test/api/v1/policy/123/version/123/example
预期结果
- 数组含2个元素时:
https://mysite.test/api/v1/policy/123/version/456/example - 数组含3个元素时:
https://mysite.test/api/v1/policy/123/version/456/example/789
正确实现方案
下面是满足需求的PowerShell函数,核心是逐个替换第一个匹配的{id},同时加入参数校验:
function Expand-Template { param( [Parameter(Mandatory=$true)] [string[]]$IdList, [Parameter(Mandatory=$true)] [string]$Template ) # 统计模板里{id}的出现次数(注意转义正则特殊字符{}) $idMatchCount = ([regex]::Matches($Template, '\{id\}')).Count # 校验数组长度是否合法 if ($IdList.Count -ne $idMatchCount -and $IdList.Count -ne ($idMatchCount + 1)) { throw "数组元素数量必须为$idMatchCount或$($idMatchCount+1),当前输入为$($IdList.Count)" } $output = $Template # 循环逐个替换第一个{id} for ($i = 0; $i -lt $idMatchCount; $i++) { # -replace的第三个参数1表示只替换第一个匹配项 $output = $output -replace '\{id\}', $IdList[$i], 1 } # 如果数组多一个元素,追加到末尾 if ($IdList.Count -eq $idMatchCount + 1) { $output += "/$($IdList[-1])" } return $output } # 测试用例 # 测试2个元素场景 $testList1 = @("123", "456") $template = "https://mysite.test/api/v1/policy/{id}/version/{id}/example" Expand-Template -IdList $testList1 -Template $template # 测试3个元素场景 $testList2 = @("123", "456", "789") Expand-Template -IdList $testList2 -Template $template
代码解释
- 统计{id}数量:用正则匹配准确统计模板中
{id}的次数,避免直接字符串分割可能带来的误差 - 参数校验:提前判断数组长度是否符合要求,不符合直接抛出明确错误
- 逐个替换:利用
-replace的第三个参数限制只替换第一个匹配项,循环对应次数,实现按顺序替换 - 追加逻辑:如果数组长度多1,直接把最后一个元素拼接到结果末尾
运行结果
- 2个元素输入时,输出:
https://mysite.test/api/v1/policy/123/version/456/example - 3个元素输入时,输出:
https://mysite.test/api/v1/policy/123/version/456/example/789
内容的提问来源于stack exchange,提问作者Douda
相关产品推荐
相关产品推荐

