(In English: How to get information about a Japanese character from 戸籍統一文字情報 site (managed by The Ministry of Justice (Japan)) with PowerShell)
問題:
ある漢字に関する情報(読みや、子の名に使える文字か等)を調べたければ、法務省の戸籍統一文字情報のページが利用できる。 ただしこのページではフォームからいちいちUnicodeのコードポイントなどを入力して検索する必要があり、複数の文字の情報を一括で取得するには向いていない。
対策:
PowerShellで、指定した文字の情報を取得するコマンドレットGet-KosekiMoji
を作成した。
このコマンドレットを使ってGet-KosekiMoji -CodePoint "90CE"
(U+90CEは「郎」のコードポイント)のように実行すると、対応する文字の情報を戸籍統一文字情報のページから検索し、その結果を取得する。
- 文字はUnicodeまたはシフトJISのコードポイントで指定する。デフォルトはUnicodeのコードポイントで、引数に
-Charset "ShiftJIS"
を指定するとシフトJISのコードポイントで検索する。 - 今のところ、BMP面の文字でのみ動作確認を行っている。
- 戻り値はPsCustomObject型で、取得する情報と格納先パラメータは以下の通り。
- 戸籍統一文字情報のページに登録されていない文字(戸籍統一文字番号が付与されていない文字)に対しては
$null
が返る。
注意事項:
このコマンドレットは、1回の呼び出しにつき、戸籍統一文字情報のページへ2回アクセスを行う。
スクリプト中で繰り返し使用する際は、戸籍統一文字情報のページに高い負荷がかからないよう、Start-Sleep
などを利用して、適切な間隔を開けて呼び出すこと。
2017/05/07追記:
当初はUnicodeのコードポイントのみ指定可能としていたが、シフトJISでも指定可能なようにオプションを追加した。 これは、シフトJISとWindows-31Jでマッピングが異なる文字(「¢」など)を検索する際、シフトJISのマッピングである「U+00A2」で検索されるべきところ、PowerShellではUnicodeのコードポイントを求める際にWindows-31Jのマッピングしか使用できず、「U+FFE0」で検索されてしまうのが避けられなかったため。
function Get-KosekiMoji { Param( [Parameter(ValueFromPipeline=$true,Mandatory=$true)] [string] $CodePoint, [string] $Charset = "Unicode" ) begin { if ($PSVersionTable.PSEdition -eq "Core") { [System.Text.Encoding]::RegisterProvider([System.Text.CodePagesEncodingProvider]::Instance) } $SearchUri = 'http://kosekimoji.moj.go.jp/kosekimojidb/mjko/PeopleSearch/EXECUTE?ihid_clickedButtonName=iimg_Search&irdo_Code={0}&itxt_Code={1}&irdo_Jyoken=AND&itxt_Yomi1=&itxt_Yomi2=&itxt_Yomi3=&islc_Kakusu1=0&islc_Kakusu2=&islc_Jis=0&ihid_ScreenId=Search&ihid_Busyu1=&ihid_Busyu2=&ihid_Busyu3=' $KskMjUri = 'http://kosekimoji.moj.go.jp/kosekimojidb/mjko/PeopleList/EXECUTE?ihid_clickedButtonName=iimag_Moji&ihid_SelectedKskMjBng={0}&ihid_SearchCount=0' $KskMjProperties = "KskMjBng", "On", "JoyoOn", "Kun", "JoyoKun", "Strokes", "JIS", "JIS2004", "Dummy1", "Unicode", "Dummy2", "UnicodeJIS2004", "Dummy3", "SJIS", "Dummy4", "SJIS2004", "KskMjKbn", "KskMjOyaKbn" $SavedProgressPreference = $ProgressPreference $ProgressPreference = "SilentlyContinue" } process { if ($Charset -eq "Unicode") { $CharsetNumber = 2 } elseif ($Charset -eq "ShiftJIS") { $CharsetNumber = 4 } else { $CharsetNumber = 2 } $SearchRequest = (Invoke-WebRequest -Uri ($SearchUri -F $CharsetNumber, $CodePoint)) $SearchHtml = [System.Text.Encoding]::GetEncoding(932).GetString($SearchRequest.RawContentStream.ToArray()); if ($SearchHtml -match '/kosekimojidb/png\?kosekiMjBng=(?<KskMjBng>[0-9]+)&pngSizeKbn=1') { $KskMjBng = $Matches.KskMjBng $KskMjResponse = (Invoke-WebRequest -Uri ($KskMjUri -F $KskMjBng)) $KskMjHtml = [System.Text.Encoding]::GetEncoding(932).GetString($KskMjResponse.RawContentStream.ToArray()); $KskMjHtml -match '<td colspan="2" nowrap class="sec">(?<KskMjOyaKbn>.+?)</td>' > $null $KskMjOyaKbn = $Matches.KskMjOyaKbn ($KskMjHtml.Split("`r") | ForEach-Object { if ($_ -like '*class="normal"*') { if ($_ -match '<.+?>(.*?)</.+?>') { $Matches.1 } } }) -join "," | Set-Variable KskMjDataCsv $KskMjDataCsv + "," + $KskMjOyaKbn | ConvertFrom-Csv -Header $KskMjProperties | Set-Variable KskMjData $KskMjData.PSObject.Properties.Remove("Dummy1") $KskMjData.PSObject.Properties.Remove("Dummy2") $KskMjData.PSObject.Properties.Remove("Dummy3") $KskMjData.PSObject.Properties.Remove("Dummy4") $KskMjData } } end { $ProgressPreference = $SavedProgressPreference } }