概要
####こんなコードです
文字列の中から指定した正規表現にマッチした部分のみを文字色を赤に変更して出力するためのクラスをPowerShellで書きました。
使用バージョン
以下のバージョンで動作確認がとれています。
Windows PowerShell 5.1.1
PowerShell 6.2.2
用法
-
InsertDlm
とHighlightKeyword
という2つのクラスを定義する(コード詳細は次項) -
次の3つを引数にしてクラス
InsertDlm
からインスタンスを作成、変数$output
に代入-
$string
: 文字列全体 -
$keyword
: 赤文字で出力したい文字列を表す正規表現 -
$delimiter
:$keyword
を赤文字にするための区切り文字($string
内で使用されないであろう文字を指定)
-
-
HighlightKeyword
のメソッドを呼び出す。文字列がラテン文字を含む場合、大文字と小文字の区別をつけるときはCaseSensitive
、つけないときはIgnoreCase
を使用する。 -
「3.」のメソッドを呼び出す際は次の3つを引数にする。
-
Case()
メソッドを呼び出して得られる値 -
$keyword
:InsertDlm
の$keyword
と同じ値を指定 -
$delimiter
:HighlightKeyword
の$delimiter
と同じ値を指定
-
#手順2.
>> $test = "This is a sentence for demonstrating how these 2 classes `
are useful and informative. But if you find some mistakes or`
simpler codes,please let me know. I'll check them immediately.`
I'm happy if these sample classes encourage you to write PowerShell classes."
>> $output = [InsertDlm]::new($test,"(,|\.)\w+","#")
#正規表現:
#| : 左右どちらかにマッチすればTrue
#\w: 任意の英数字、アンダーバー、日本語などの表意文字にマッチすればTrue
#+: 最長一致
#手順3.と手順4.
>> [HighlightKeyword]::IgnoreCase($output.IgnoreCase(),"(,|\.)\w+","#")
実行結果
クラス詳細
InsertDlm
コンストラクタ
InsertDlm(String, String, String)
文字列の中に指定する正規表現があった場合、その前後に区切り文字を挿入するために使用するInsertDlm
クラスのインスタンスを初期化
メソッド
CaseSensitive()
: 正規表現がマッチするか判別する際、大文字と小文字を区別する
IgnoreCase()
: 正規表現がマッチするか判別する際、大文字と小文字を区別しない
アプローチ
Regex
クラス (System.Text.RegularExpressions
) を使用し、正規表現が文字列内でマッチした場合、Replace
メソッドを使用してマッチ部分の前後に区切り文字を挿入。
コード
class InsertDlm{
[string]$string
[string]$keyword
[string]$delimiter
[string]CaseSensitive(){
$dlm = $this.delimiter
return [Regex]::Replace($this.string,"($($this.keyword))","$dlm`$1$dlm")
}
[string]IgnoreCase(){
$dlm = $this.delimiter
return [Regex]::Replace($this.string,"($($this.keyword))","$dlm`$1$dlm", "IgnoreCase")
}
InsertDlm([string]$string,[string]$keyword,[string]$delimiter){
[string]$this.string = $string
[string]$this.keyword = $keyword
[string]$this.delimiter = $delimiter
}
}
出力テスト
>> $sample = "This is a test sentence."
>> [InsertDlm]::new($sample,"T","#").IgnoreCase() ;`
>> [InsertDlm]::new($sample,"T","#").CaseSensitive()
HighlightKeyword
#####メソッド
Output(String, String, String)
:
文字列を区切り文字で分割し、その個々の要素に対して正規表現にマッチするか検証する。マッチしない場合は文字色をデフォルトのまま出力し、する場合は赤に変えて出力する。
#####アプローチ
InsertDlm
で挿入した区切り文字と同じものをHighlightKeyword
でも指定することで、文字列内にマッチするものがあれば配列内にマッチ部分だけの要素ができることになる。
パイプラインを使えば文字列の先頭から一要素ずつ判別させることができる。
#####コード
class HighlightKeyword{
static[void]IgnoreCase([string]$string, [string]$keyword, [string]$delimiter){
@($string -split $delimiter)|
ForEach-Object{
if($_ -match $keyword){
Write-Host $_ -ForegroundColor Red -NoNewline
}
else{
Write-Host $_ -NoNewline
}
}
}
static[void]CaseSensitive([string]$string, [string]$keyword, [string]$delimiter){
@($string -split $delimiter)|
ForEach-Object{
if($_ -cmatch $keyword){
Write-Host $_ -ForegroundColor Red -NoNewline
}
else{
Write-Host $_ -NoNewline
}
}
}
}
#####出力テスト
>> #前の例の続き
>> $replacedSample = [InsertDlm]::new($sample,"T","#")
>> [HighlightKeyword]::IgnoreCase($replacedsample.IgnoreCase,"T","#") + "`n";
>> [HighlightKeyword]::CaseSensitive($replacedsample.CaseSensitive,"T","#")
という感じになりました。
##リファレンス
Regular Expressions Options
System.Text.RegularExpressions Namespace
Lee Homes, Windows PowerShell Cookbook 3rd Edition (O'reilly)
Lee Homes, Windows PowerShellクックブック (マイクロソフト社)
山田祥寛, 独習C# 新版 (翔泳社)
##最後に
これは関数にしたほうが圧倒的にやりやすいと書きながら思いました。
近い将来、これを関数に書き換えたものを記事にしたいと思います。