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

PowerShell实现CSV文件应用名称模糊匹配的问题求助

解决CSV文件中应用名称的跨格式匹配问题

原脚本的核心错误

你的脚本返回0匹配的原因有几个关键问题:

  • 标志位初始化位置错误:$allPartsMatch在循环外初始化,一旦某次匹配失败设为$false后,后续所有循环都会沿用这个值,永远不会触发匹配成功的逻辑。
  • 数组匹配逻辑错误:$ProductSplit -notcontains $ApplicationSplit是在检查$ProductSplit数组是否包含整个$ApplicationSplit数组,而不是检查后者的元素是否存在于前者中,完全不符合你的匹配需求。
  • 匹配逻辑方向错误:你需要的是识别两个名称的核心重叠部分,而不是要求一个名称的所有片段都包含在另一个里——比如你的例子中,"Continuous MUI"和"v2022.002.20191"是各自独有的片段,原逻辑会直接判定不匹配。

可行的解决方案

针对应用名称的格式差异,推荐两种高效的匹配思路:

思路1:基于核心关键词的精准匹配

先定义每个应用的核心标识规则(比如提取版本号、后缀前的核心名称),再用这些核心标识做匹配。

示例脚本

# 导入CSV文件
$Products01 = Import-CSV 'C:\Temp\ProductsList01.csv' -Delimiter ";"
$Products02 = Import-CSV 'C:\Temp\ProductList02.csv' -Delimiter ";"

# 存储匹配结果的数组(用数组比哈希表更适合后续导出CSV)
$MatchingApps = @()

# 遍历第一个CSV的每个应用
foreach ($prod in $Products01) {
    $prodName = $prod.Product
    # 提取核心名称:去掉版本号、后缀(比如Continuous MUI这类)
    # 正则规则:匹配到第一个数字开头的部分或特定后缀前的内容
    $prodCore = [regex]::Match($prodName, "^(.*?)(?=\s+v?\d|Continuous|MUI)").Value.Trim()
    
    # 遍历第二个CSV找匹配
    foreach ($app in $Products02) {
        $appName = $app.Column1
        $appCore = [regex]::Match($appName, "^(.*?)(?=\s+v?\d|Continuous|MUI)").Value.Trim()
        
        # 核心名称一致则记录匹配
        if ($prodCore -eq $appCore) {
            $MatchingApps += [PSCustomObject]@{
                Product01 = $prodName
                Product02 = $appName
                CoreName = $prodCore
            }
            # 找到匹配后跳出内层循环,避免重复匹配(如果一个应用对应多个的话可以去掉)
            break
        }
    }
}

# 输出结果到控制台
$MatchingApps | Format-Table -AutoSize

# 导出匹配结果到CSV(可选)
$MatchingApps | Export-CSV 'C:\Temp\MatchedApps.csv' -Delimiter ";" -NoTypeInformation

思路2:基于字符串相似度的模糊匹配

如果核心标识规则不好定义,可以用字符串相似度算法(比如Levenshtein距离)来匹配相似名称,适合格式差异较大但名称接近的场景。

示例脚本(包含相似度计算函数)

# 计算Levenshtein距离(字符串相似度)的函数
function Get-StringSimilarity {
    param(
        [string]$String1,
        [string]$String2
    )
    $len1 = $String1.Length
    $len2 = $String2.Length
    $matrix = New-Object 'int[,]' ($len1 + 1), ($len2 + 1)
    
    for ($i = 0; $i -le $len1; $i++) { $matrix[$i, 0] = $i }
    for ($j = 0; $j -le $len2; $j++) { $matrix[0, $j] = $j }
    
    for ($i = 1; $i -le $len1; $i++) {
        for ($j = 1; $j -le $len2; $j++) {
            $cost = if ($String1[$i-1] -eq $String2[$j-1]) { 0 } else { 1 }
            $matrix[$i, $j] = [math]::Min(
                [math]::Min($matrix[$i-1, $j] + 1, $matrix[$i, $j-1] + 1),
                $matrix[$i-1, $j-1] + $cost
            )
        }
    }
    # 返回相似度(1 - 距离/最长字符串长度)
    $maxLen = [math]::Max($len1, $len2)
    if ($maxLen -eq 0) { return 1.0 }
    return 1.0 - ($matrix[$len1, $len2] / $maxLen)
}

# 导入CSV
$Products01 = Import-CSV 'C:\Temp\ProductsList01.csv' -Delimiter ";"
$Products02 = Import-CSV 'C:\Temp\ProductList02.csv' -Delimiter ";"

$MatchingApps = @()
$similarityThreshold = 0.7 # 相似度阈值,可调整

foreach ($prod in $Products01) {
    $prodName = $prod.Product
    $bestMatch = $null
    $highestSimilarity = 0
    
    foreach ($app in $Products02) {
        $appName = $app.Column1
        $similarity = Get-StringSimilarity $prodName $appName
        
        if ($similarity -ge $similarityThreshold -and $similarity -gt $highestSimilarity) {
            $highestSimilarity = $similarity
            $bestMatch = $appName
        }
    }
    
    if ($bestMatch) {
        $MatchingApps += [PSCustomObject]@{
            Product01 = $prodName
            Product02 = $bestMatch
            Similarity = [math]::Round($highestSimilarity, 2)
        }
    }
}

# 输出结果
$MatchingApps | Format-Table -AutoSize

关键优化点说明

  • 用PSCustomObject存储结果,比哈希表更灵活,方便后续导出CSV或格式化输出。
  • 核心匹配思路优先:对于应用名称,精准提取核心标识比模糊匹配更可靠,建议先整理出常见的后缀/版本前缀规则(比如v\d、Continuous、MUI、x64等),优化正则表达式。
  • 循环内的提前跳出:找到匹配后跳出内层循环,减少不必要的计算,提升处理效率(适合数百条数据的场景)。

内容的提问来源于stack exchange,提问作者Fred Eric S

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 15:01:11