LoginSignup
0
2

More than 3 years have passed since last update.

PowerShellでC#っぽいクラスを書いて楽しく文字列操作

Posted at

概要

こんなコードです

文字列の中から指定した正規表現にマッチした部分のみを文字色を赤に変更して出力するためのクラスをPowerShellで書きました。
qiita_august_5.PNG

使用バージョン

以下のバージョンで動作確認がとれています。
Windows PowerShell 5.1.1
PowerShell 6.2.2

用法

  1. InsertDlmHighlightKeywordという2つのクラスを定義する(コード詳細は次項)
  2. 次の3つを引数にしてクラスInsertDlmからインスタンスを作成、変数$outputに代入

    1. $string: 文字列全体
    2. $keyword: 赤文字で出力したい文字列を表す正規表現
    3. $delimiter: $keywordを赤文字にするための区切り文字($string内で使用されないであろう文字を指定)
  3. HighlightKeywordのメソッドを呼び出す。文字列がラテン文字を含む場合、大文字と小文字の区別をつけるときはCaseSensitive、つけないときはIgnoreCaseを使用する。

  4. 「3.」のメソッドを呼び出す際は次の3つを引数にする。

    1. Case()メソッドを呼び出して得られる値
    2. $keyword: InsertDlm$keywordと同じ値を指定
    3. $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+","#")

実行結果

カンマのあとにスペースが抜けているのを発見できました。
qiita_august_1.PNG

クラス詳細

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()
出力

qiita_august_6.PNG

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","#")

出力

qiita_august_7.PNG

という感じになりました。

リファレンス

Regular Expressions Options
System.Text.RegularExpressions Namespace
Lee Homes, Windows PowerShell Cookbook 3rd Edition (O'reilly)
Lee Homes, Windows PowerShellクックブック (マイクロソフト社)
山田祥寛, 独習C# 新版 (翔泳社)

最後に

これは関数にしたほうが圧倒的にやりやすいと書きながら思いました。
近い将来、これを関数に書き換えたものを記事にしたいと思います。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2