6

これはテクニックの問題ですが、演習として、正規表現をパラメーターとして使用して、パイプ入力を受け入れるPSを作成し、正規表現に一致するテキストを強調表示することを目的としています。

私が情報を見つけることができない部分は、テキストの照合、バッファへのキャプチャ、またはテキストの置き換えが簡単であるということです。ただし、一致したテキストを元のテキストであるカラーコントロールに置き換えてから、前の色に戻す必要があります。書き込み出力以外の方法で色出力を生成する方法が見つからないようです。また、1回の書き込みで色を分離することもできません。つまり、次のようになります。

-正規表現のマッチング

-write-一致する前にすべてのテキストをデフォルトの色で-NoNewLineを使用してホストします

-書き込み-一致をホストし、-NoNewLineを使用します

-残りを書き込みホストします

これは面倒に思えますが、複数の一致をサポートしたい場合はさらに面倒になります。これを行うためのより雄弁な方法はありますか?

4

3 に答える 3

6

Write-Hostこれを行う正しい方法です。.Index結果のオブジェクトのand.Lengthプロパティを使用してMatch、一致したテキストがどこにあるかを判断します。インデックスを追跡するのに少し注意する必要があります:)

これは複数の試合で機能し、ひどく乱雑なIMOではありません。

function ColorMatch
{
   param(
      [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
      [string] $InputObject,

      [Parameter(Mandatory = $true, Position = 0)]
      [string] $Pattern
   )

   begin{ $r = [regex]$Pattern }
   process
   {
       $ms = $r.Matches($inputObject)
       $startIndex = 0

       foreach($m in $ms)
       {
          $nonMatchLength = $m.Index - $startIndex
          Write-Host $inputObject.Substring($startIndex, $nonMatchLength) -NoNew
          Write-Host $m.Value -Back DarkRed -NoNew
          $startIndex = $m.Index + $m.Length
       }

       if($startIndex -lt $inputObject.Length)
       {
          Write-Host $inputObject.Substring($startIndex) -NoNew
       }

       Write-Host
   }
}
于 2012-09-26T20:54:40.443 に答える
1

これは、latkinの答えの拡張です。ここでは、Matchオブジェクトを拡張して、この目的(およびその他の目的)でより簡単に処理できるようにしています。

function Split-Match {
    param([Parameter(Mandatory = $true)]
    $match
    )
    $sections = @()
    $start = 0
    $text = $m.Line
    foreach ($m in $match.Matches) {
        $i = $m.Index
        $l = $m.Length

        $sections += $false, $text.Substring($start, $i - $start)
        $sections += $true, $text.Substring($i, $l)
        $start = $i + $l
    }
    $sections += $false, $text.Substring($start)
    $match | Add-Member -Force Sections $sections
    $match
}

function Write-Match {
    param([Parameter(Mandatory = $true)]
    $match
    )
    $fg = "White"
    $bg = "Black"
    foreach($s in $match.Sections) {
        if ($s.GetType() -eq [bool]) {
            if ($s) {
                $fg = "White"
                $bg = "Red"
            } else {
                $fg = "White"
                $bg = "Black"
            }
        } else {
            Write-Host -NoNewline -ForegroundColor $fg -BackgroundColor $bg $s
        }
    }
    Write-Host
}

$string = @'
Match this A
Not this B
Not this C
But this A
'@
$m = $string | select-string -CaseSensitive -AllMatches "A"
$m = Split-Match $m
Write-Match $m

出力

于 2019-03-29T15:24:13.210 に答える
1

あるいは、ANSI / VT100フォーマットを使用する方が簡単で、はるかに広い範囲の色で必要なことを正確に実行できることがわかりました。

$esc=[char]27
$fileContents="abc455315testing123455315abc"
$keywordSearch="testing123"

$fileContents -replace $keywordSearch,"$esc[38;2;0;200;255m$keywordSearch$esc[0m"

これは、PowerShellISEではなくPowerShellコンソールウィンドウでのみ機能することに注意してください。このウィキペディアのページも役に立ちました。具体的には、色の選択に関するこの行:

ESC[38;2;⟨r⟩;⟨g⟩;⟨b⟩mRGB前景色を選択

于 2019-10-10T03:35:52.267 に答える