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

PowerShell使用LineNumber回溯文件行查找指定城镇对应街道

PowerShell指定城镇匹配街道条目实现方案

核心问题梳理

目标文本存在两种街道-城镇排版格式:

ACACIA AVENUE,
  Bridral  Town
  Sandhurstpool  City 
ACCENT DRIVE, Sandhurstpool  City
BERWICK ROAD, Bridral  Town
  • 格式1:街道名(全大写带末尾逗号)和城镇名在同一行
  • 格式2:街道名单独占一行,下方缩进排列所属的多个城镇

原有代码的缺陷:

  • 全大写街道匹配正则写法错误,字符组内的$会被识别为字面量,无法正确匹配行尾
  • 未提前加载文件全量行内容,拿到城镇匹配行号后无法向前回溯遍历
  • 未设置回溯终止边界,容易跨街道条目误匹配

实现逻辑

  • 提前将文件所有行读入内存数组,注意Select-String返回的LineNumber从1开始计数,数组索引从0开始,转换时需要减1
  • 修正街道匹配正则,精准识别全大写格式的街道名称
  • 匹配到独占行的城镇条目时,从当前行的上一行开始逐行向上遍历:
    • 遍历到匹配全大写规则的街道行时,记录该街道为当前城镇的下辖条目,终止回溯
    • 遍历到无缩进的非空行(即其他街道/条目边界)时,直接终止回溯,避免错配其他街道
  • 使用哈希集存储结果,自动去重,兼容同街道分属多城镇的场景

完整实现代码

$listing = 'streetNameTest.txt'
$targetTown = 'Bridral'
# 匹配全大写街道名的正则,捕获组1为纯街道名称
$streetRegex = '^\s*([A-Z0-9 ]+),\s*'
# 全量读取文件行到内存,支持回溯
$allLines = Get-Content -Path $listing
$matchedStreets = [System.Collections.Generic.HashSet[string]]::new()

Select-String -Pattern $targetTown -Path $listing -CaseSensitive | ForEach-Object {
    $currentLineNo = $_.LineNumber
    $currentLineText = $_.Line.Trim()

    # 处理同行包含街道和城镇的场景
    if ($currentLineText -match $streetRegex) {
        $street = $matches[1].Trim()
        $matchedStreets.Add($street) | Out-Null
        Write-Host "同行匹配成功,行号$currentLineNo 街道:$street"
        return
    }

    # 处理城镇独占一行,向上回溯的场景
    Write-Host "行号$currentLineNo 仅匹配到城镇名,开始向上回溯查找对应街道"
    $searchIndex = $currentLineNo - 2 # 转换为数组索引,从上一行开始查找
    while ($searchIndex -ge 0) {
        $checkLine = $allLines[$searchIndex]
        # 找到全大写街道行,记录结果并终止回溯
        if ($checkLine -match $streetRegex) {
            $street = $matches[1].Trim()
            $matchedStreets.Add($street) | Out-Null
            Write-Host "回溯匹配成功,街道行号$($searchIndex+1) 街道:$street"
            break
        }
        # 碰到无缩进的非空边界行,停止回溯避免错配
        if ($checkLine.Trim() -and -not $checkLine.StartsWith(' ') -and -not $checkLine.StartsWith("`t")) {
            Write-Warning "回溯至行号$($searchIndex+1)碰到条目边界,终止查找"
            break
        }
        $searchIndex--
    }
}

Write-Host "`n===== 城镇[$targetTown]下辖街道列表 ====="
$matchedStreets | ForEach-Object { Write-Host "- $_" }

示例运行结果

针对给出的测试文本,运行后输出如下:

回溯匹配成功,街道行号1 街道:ACACIA AVENUE
同行匹配成功,行号5 街道:BERWICK ROAD

===== 城镇[Bridral]下辖街道列表 =====
- ACACIA AVENUE
- BERWICK ROAD

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 00:24:42