Мне нравится подход Rynant .Вот альтернативная реализация, использующая -split
вместо IndexOf
:
filter ColorWord( [string]$word, [ConsoleColor]$color ) {
$later = $false
$_ -split [regex]::Escape( $word ) | foreach {
if( $later ) { Write-Host "$word" -NoNewline -ForegroundColor $color }
else { $later = $true }
Write-Host $_ -NoNewline
}
Write-Host
}
Разделение включает пустые строки, если строка начинается или заканчивается заданнымword, отсюда и дополнительная логика «если не первый».
Edit: После комментария Rynant, вот еще одна реализация, которая поддерживает как простые, так и регулярные выражения:
filter ColorPattern( [string]$Pattern, [ConsoleColor]$Color, [switch]$SimpleMatch ) {
if( $SimpleMatch ) { $Pattern = [regex]::Escape( $Pattern ) }
$split = $_ -split $Pattern
$found = [regex]::Matches( $_, $Pattern, 'IgnoreCase' )
for( $i = 0; $i -lt $split.Count; ++$i ) {
Write-Host $split[$i] -NoNewline
Write-Host $found[$i] -NoNewline -ForegroundColor $Color
}
Write-Host
}
Вывод следующих примеров показывает разницу:
PS> '\d00\d!' | ColorPattern '\d' 'Magenta' -Simple
<strong>\d</strong>00<strong>\d</strong>!
PS> '\d00\d!' | ColorPattern '\d' 'Magenta'
\d<strong>00</strong>\d!