You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell正则匹配URL下划线后无法完成替换问题求助

替换XLF文件中URL的下划线为%95

我需要遍历双语XLF文件,检测<trans-unit>的<source>节点里带下划线的URL,把下划线替换成%95(适配第三方工具规则,无法修改工具)。我试过正则((https?://\S*?)_([^)\s]*?))能匹配目标URL,但代码没法替换URL里所有下划线,尝试了两段代码都有问题:

原尝试代码1(仅替换单个下划线)

function ReplaceUnderscoresInURLs($xlfContent) {
    foreach ($transUnit in $xlfContent.xliff.file.body.'trans-unit') {
        $sourceNode = $transUnit.source

        $matches = [regex]::Matches($sourceNode.InnerXml, '\((https?://[^\s&quot;]*?)_([^)\s]*?)\)')

        foreach ($match in $matches) {
            $matchedLink = $match.Groups[0].Value

            $matchedLinkReplaced = $matchedLink -replace '_', '%95'

            $sourceNode.InnerXml = $sourceNode.InnerXml -replace [regex]::Escape($matchedLink), $matchedLinkReplaced
        }
    }

    return $xlfContent
}

问题:正则每次仅匹配含单个下划线的片段,循环处理时无法覆盖URL内所有下划线,导致替换不彻底。

原尝试代码2(错误删除内容)

function ReplaceUnderscoresInParentheses($xlfContent) {
    $xlfContent = $xlfContent -replace '(?&lt;=\()\S*_(?=\S*?\))', '%95'
    return $xlfContent
}

问题:正则逻辑错误,会删除第一个下划线之前的所有内容,破坏URL结构。


解决方案

方案1:使用正则回调函数批量替换

直接匹配括号内的完整URL,在回调中替换所有下划线:

function ReplaceUnderscoresInURLs($xlfContent) {
    foreach ($transUnit in $xlfContent.xliff.file.body.'trans-unit') {
        $sourceNode = $transUnit.source
        # 匹配括号内的完整HTTP/HTTPS URL
        $sourceNode.InnerXml = [regex]::Replace($sourceNode.InnerXml, '\((https?://[^)]+)\)', {
            param($match)
            # 提取URL并替换所有下划线为%95
            $url = $match.Groups[1].Value
            $replacedUrl = $url -replace '_', '%95'
            return "($replacedUrl)"
        })
    }
    return $xlfContent
}

优势:一次性处理完整URL,确保所有下划线都被替换,代码简洁高效。

方案2:改进遍历匹配逻辑(倒序处理)

如果需要保留遍历节点的逻辑,可通过倒序处理匹配结果避免位置偏移:

function ReplaceUnderscoresInURLs($xlfContent) {
    foreach ($transUnit in $xlfContent.xliff.file.body.'trans-unit') {
        $sourceNode = $transUnit.source
        # 匹配所有括号内的HTTP/HTTPS URL
        $matches = [regex]::Matches($sourceNode.InnerXml, '\((https?://[^)]+)\)')
        # 倒序处理,防止替换后影响后续匹配位置
        for ($i = $matches.Count - 1; $i -ge 0; $i--) {
            $match = $matches[$i]
            $fullMatch = $match.Groups[0].Value
            $url = $match.Groups[1].Value
            $replacedUrl = $url -replace '_', '%95'
            $replacedFullMatch = "($replacedUrl)"
            # 替换指定位置的内容
            $sourceNode.InnerXml = $sourceNode.InnerXml.Substring(0, $match.Index) + $replacedFullMatch + $sourceNode.InnerXml.Substring($match.Index + $fullMatch.Length)
        }
    }
    return $xlfContent
}

优势:精准控制替换位置,适合复杂XML节点场景。


测试示例

使用提供的XLF文件测试后,<trans-unit id="3">的<source>内容会从:

<source>Lorem Ipsum 3 with [Link](https://example.com/with_underscore)</source>

变为:

<source>Lorem Ipsum 3 with [Link](https://example.com/with%95underscore)</source>

内容的提问来源于stack exchange,提问作者Hateforms

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 21:53:35