首页 > 解决方案 > 用于匹配和替换部分匹配模式的 Powershell

问题描述

整个星期都在发疯,无法解决这个问题。我有一个字典单词文件,一次会有几百万个单词,现在让我们假设它只是一个文本文件“Words.txt”,它有:

应用程序
苹果
应用
酒吧
蝙蝠
面糊
帽
首都
糖果

我需要它做的是将每个字符串与文件的其余部分进行匹配,并且只写入第一次命中的输出。这将按字母顺序排列。

示例上述单词的所需输出将是:

应用程序 - 由于首先看到模式“应用程序”并跳过“苹果”和“应用程序”
条形——由于图案“条形”,独一无二
蝙蝠 - 由于图案“蝙蝠”首先出现并跳过“蝙蝠”
Cap - 由于首先看到模式“Cap”并跳过“Capital”
糖果 - 由于图案“糖果”,独一无二

我绝对无法弄清楚如何做到这一点是如何忽略初始命中后发生的匹配并转移到“新”模式。如果其他冗余模式被覆盖或只是跳过,那也没关系。

我有一个匹配模式的脚本,但我不知道如何得到所需的输出:(有什么帮助吗?!?!


$Words = "C:\Words.txt"

[System.Collections.ArrayList]$WordList = Get-Content $Words

$Words
$Words2 = $Words
$i = 0
$r = 0
Foreach ($item in $Words)
{
    foreach ($item2 in $Words2)
    {
            if ($item2 -like "$item*")
            {
            write-host $("Match " + [string]$i + " " + $item + " " + [string]$r + " " + $item2)
            }

            $r++
    }
$i++
} 

标签: powershellpattern-matching

解决方案


一行一行地处理这些行并将它们与最近的唯一前缀进行比较就足够了:

$prefix = '' # initialize the prefix pattern
foreach ($line in [IO.File]::ReadLines('C:\Words.txt')) {
  if ($line -like $prefix) { continue } # same prefix, skip
  $line               # output new unique prefix
  $prefix = "$line*"  # save new prefix pattern
}

注意:由于您提到输入文件很大,因此我使用System.IO.File.ReadLines而不是Get-Content读取文件,以获得卓越的性能。

注意:无论如何,您的示例输入路径都是完整路径,但请务必始终将完整路径传递给 .NET 方法,因为 .NET 的工作目录通常与 PowerShell 的不同。

如果将foreach循环包装& { ... }Set-Content.

但是,使用 .NET 类型进行保存也会表现得更好 - 请参阅此答案的底部部分。


推荐阅读