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

PowerShell 7正则提取文件名国家列表失效及Regexr匹配异常求助

从文件名中提取国家名称的正则修正方案

问题背景

需要从文件名列表中提取括号内的国家名称(支持逗号分隔的多个国家),原正则在PowerShell 7中出现匹配错误,例如将(USA) (Proto)中的USA) (Proto全部纳入匹配结果;同时在Regexr工具中处理Mein Weg (USA, Germany) (En)时,会出现跨行匹配的异常。

原使用的正则表达式:

$regex = "^[^\(]* \(([\b(USA|Japan|Europe|Germany|Canada)\b,\s]*)\).*$"

示例文件名列表:

3-D Genesis (USA) (Proto)
Wallaby!! - Usagi no Kuni no Kangaroo Race (Japan) (Wii U Virtual Console)
UWOL - Quest for Money (World) (v1.1) (Aftermarket) (Unl)
Super Star Soldier (USA, Europe) (Wii U Virtual Console)
Soldier Blade (USA, Europe) (Wii U Virtual Console)
Mein Weg (USA, Germany) (En)
Challenge (Canada)

原正则的错误匹配结果:

Name                           Value
----                           -----
1                              USA) (Proto
0                              3-D Genesis (USA) (Proto)

原正则的问题分析

  • 词边界误用:\b被放在字符组内,无法起到单词边界的限制作用,反而会被解析为普通字符,导致无法精准匹配国家名称的边界。
  • 字符组逻辑错误:[\b(USA|Japan|Europe|Germany|Canada)\b,\s]*是字符组而非分支匹配组,|会被当作普通字符处理,意味着会匹配括号、国家名称的单个字符、逗号、空格的任意组合,自然会把后续的) (Proto这类无关内容包含进来。
  • 跨行匹配隐患:.*在多行模式下会匹配换行符,导致处理末尾行时会跨到下一行内容。

修正后的正则与实现代码

基础匹配正则(PowerShell 7)

$regex = "^[^(]* \((?:(USA|Japan|Europe|Germany|Canada)(?:, )?)+\).*$"

正则逻辑拆解

  • ^[^(]* :匹配文件名开头到第一个 ((空格加左括号)之前的主体内容
  • \(:匹配左括号
  • (?:(USA|Japan|Europe|Germany|Canada)(?:, )?)+:非捕获组,用于匹配一个或多个国家名称:
    • (USA|Japan|Europe|Germany|Canada):捕获指定范围内的国家名称
    • (?:, )?:非捕获组,处理单个国家或多个国家之间的, 分隔符
  • \):匹配右括号
  • .*$:匹配括号后的剩余内容,确保整行匹配

提取所有匹配国家的完整代码

如果需要提取单个文件名中的所有国家(包括多个逗号分隔的情况),可以使用[regex]::Matches()来获取所有匹配项:

# 定义目标国家列表
$targetCountries = "USA", "Japan", "Europe", "Germany", "Canada"
# 构建正则模式
$regexPattern = "\b(" + ($targetCountries -join "|") + ")\b"

# 示例文件名列表
$fileNameList = @(
    "3-D Genesis (USA) (Proto)",
    "Wallaby!! - Usagi no Kuni no Kangaroo Race (Japan) (Wii U Virtual Console)",
    "UWOL - Quest for Money (World) (v1.1) (Aftermarket) (Unl)",
    "Super Star Soldier (USA, Europe) (Wii U Virtual Console)",
    "Soldier Blade (USA, Europe) (Wii U Virtual Console)",
    "Mein Weg (USA, Germany) (En)",
    "Challenge (Canada)"
)

# 遍历处理每个文件名
foreach ($name in $fileNameList) {
    $matches = [regex]::Matches($name, $regexPattern)
    $extractedCountries = $matches.Value -join ", "
    if ($extractedCountries) {
        Write-Host "文件名: $name`n提取的国家: $extractedCountries`n"
    } else {
        Write-Host "文件名: $name`n未匹配到指定国家`n"
    }
}

验证结果

运行上述代码后,会得到正确的提取结果:

  • 3-D Genesis (USA) (Proto) → 提取的国家: USA
  • Wallaby!! - Usagi no Kuni no Kangaroo Race (Japan) (Wii U Virtual Console) → 提取的国家: Japan
  • UWOL - Quest for Money (World) (v1.1) (Aftermarket) (Unl) → 未匹配到指定国家
  • Super Star Soldier (USA, Europe) (Wii U Virtual Console) → 提取的国家: USA, Europe
  • Soldier Blade (USA, Europe) (Wii U Virtual Console) → 提取的国家: USA, Europe
  • Mein Weg (USA, Germany) (En) → 提取的国家: USA, Germany
  • Challenge (Canada) → 提取的国家: Canada

补充注意事项

  • PowerShell的-match运算符默认是单行模式,.*不会匹配换行符,可避免跨行匹配问题;如果使用[regex]::Matches(),可指定[System.Text.RegularExpressions.RegexOptions]::Singleline确保行为一致。
  • 使用\b单词边界可以避免误匹配包含目标国家名称的其他字符串(比如不会把USAA误识别为USA)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 23:42:51