PowerShell匹配文件中数量-描述-价格格式及数组存储问题
问题解决方案
核心问题分析
你的代码存在两个关键问题:
- 正则表达式匹配规则不够通用,无法覆盖多位数数量、无千分位价格等场景,且描述部分的匹配逻辑错误(
\D会排除空格,导致无法匹配带空格的商品名)。 - 结果数组未正确累加,循环内每次覆盖
$results变量,最终只能保留最后一行的匹配结果,无匹配时数组为空。
修正后的正则表达式
针对「数量(带两位小数)+ 商品描述(含空格)+ 价格(支持千分位逗号、固定两位小数)」的格式,优化后的正则:
$pattern = '^(\d+\.\d{2})\s+([^0-9,]+?)\s+(\d{1,3}(?:,\d{3})*\.\d{2})$'
各部分说明:
^(\d+\.\d{2}):匹配开头的数量,支持多位整数(如10.00),固定两位小数\s+:匹配数量与描述之间的任意多个空格([^0-9,]+?):非贪婪匹配商品描述,排除数字和逗号(避免与价格开头混淆),保留空格\s+:匹配描述与价格之间的任意多个空格(\d{1,3}(?:,\d{3})*\.\d{2})$:匹配结尾的价格,支持千分位逗号(如26,805.00)或无千分位(如123.00),固定两位小数,$确保匹配到行尾
修正后的完整函数
function pasar_a_word($archivo) { $content = Get-Content "$root\UNB\FACTURA_FINAL\$archivo" $pattern = '^(\d+\.\d{2})\s+([^0-9,]+?)\s+(\d{1,3}(?:,\d{3})*\.\d{2})$' # 初始化空数组存储匹配结果 $results = @() Write-Host "FUNCION PASAR A WORD" foreach ($line in $content) { # 跳过空行,避免无效匹配 if ([string]::IsNullOrWhiteSpace($line)) { continue } $match = [regex]::Match($line, $pattern) if ($match.Success) { # 将匹配结果封装为自定义对象,方便后续处理 $item = [PSCustomObject]@{ Quantity = $match.Groups[1].Value Description = $match.Groups[2].Value.Trim() # 去除描述前后多余空格 Price = $match.Groups[3].Value } # 将对象添加到结果数组 $results += $item } } # 输出指定索引的结果(示例为索引1,即第二条匹配项) if ($results.Count -gt 0) { Write-Host "第2条匹配结果:" Write-Host "数量: $($results[1].Quantity) | 描述: $($results[1].Description) | 价格: $($results[1].Price)" } else { Write-Host "未匹配到任何有效行" } # 返回结果数组,方便外部调用时使用 return $results }
关键优化点
- 使用
foreach循环遍历文本行,比for循环更简洁易读 - 初始化空数组并通过
+=累加匹配结果,避免变量被覆盖 - 将匹配结果封装为
PSCustomObject,后续可直接导出到CSV、Word等格式 - 跳过空行,减少无效匹配尝试
内容的提问来源于stack exchange,提问作者Juan Manuel Sanchez
相关产品推荐
相关产品推荐

