【powershell】정규 표현에 매치한 개소를 색 첨부로 강조 표시한다

2020/05/03 업데이트



ANSI 이스케이프 시퀀스를 사용하는 방법 에서 더 간단하게 구현할 수 있었습니다.

만든 것




콘솔 에뮬레이터는 Cmder을(를) 좋아합니다.

환경


PS > $PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.1.18362.145
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.18362.145
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

코드


function Write-StringHighlight {
    <#
    .SYNOPSIS
    文字列内の指定箇所を強調表示する
    ・パイプライン経由での入力にのみ対応
    .PARAMETER pattern
    検索パターン
    .PARAMETER case
    指定時は大文字小文字を区別
    .PARAMETER color
    強調箇所の色
    .PARAMETER plainColor
    強調しない箇所の色
    .PARAMETER continuous
    指定時は出力後に改行しない
    #>
    param (
        [string]$pattern = ".",
        [switch]$case,
        [ValidateSet("White", "Black", "Blue", "DarkBlue", "Green", "DarkGreen", "Cyan", "DarkCyan", "Red", "DarkRed", "Magenta", "DarkMagenta", "Yellow", "DarkYellow", "Gray", "DarkGray")][string]$color = "Yellow",
        [ValidateSet("White", "Black", "Blue", "DarkBlue", "Green", "DarkGreen", "Cyan", "DarkCyan", "Red", "DarkRed", "Magenta", "DarkMagenta", "Yellow", "DarkYellow", "Gray", "DarkGray")][string]$plainColor = "Gray",
        [switch]$continuous
    )

    $capture = "(?<pre>.*?)(?<main>{0})(?<post>.*)" -f $pattern
    if ($case) {
        $r = [regex]$capture
    }
    else {
        $r = [regex]"(?i)$capture"
    }

    $loopFlag = $true
    if ($pattern.Substring(0,1) -eq "^") {
        $loopFlag = $false
    }

    foreach ($i in $input) {
        Do {
            if (-not $r.IsMatch($i)) {
                break
            }
            $m = $r.Matches($i)
            Write-Host $m[0].Groups["pre"].Value -ForegroundColor $plainColor -NoNewline
            Write-Host $m[0].Groups["main"].Value -ForegroundColor Black -BackgroundColor $color -NoNewline
            $i = $m[0].Groups["post"].Value
        } while ($loopFlag)
        Write-Host $i -ForegroundColor $plainColor -NoNewline:$continuous
    }
}

# Alias
Set-Alias "hilight" Write-StringHighLight

개인적으로는 $profile 에 써 두어 각종 cmdlet 내에서 사용해 주고 있습니다.

메커니즘



자동 변수 $input 에서 파이프라인에서 입력을 받아 각 요소를 처리합니다.
알고리즘이라고 할 정도는 아니지만, 정규 표현의 이름 첨부 캡쳐 ( 참고 기사 )로 캐릭터 라인을 매치 개소와 그 전후에 분할해, 루프를 반복하면서 후방으로 매치 개소를 탐색합니다. 사전에 ^ 의 유무를 판정하고 있는 것은 루프 마다 선두 부분에 매치해 버리기 때문입니다.
Write-Host 에 의한 출력이므로, 파이프 처리의 도중에서의 필터적인 사용법은 할 수 없습니다. 어디까지나 검색 결과를 시각적으로 확인하기 위해서 작성한 cmdlet입니다.

별칭의 hilight 는 히데마루 에디터 의 설정 리스펙트입니다.

좋은 웹페이지 즐겨찾기