指定すると、単一の文字列ではなく、文字列の配列を出力する。"今日はいい天気ですね。"今日はいい天気ですね。/出力:今日は/いい/天気ですね/。"今日はいい天気ですね。"今日はいい天気ですね。Yomi出力:きょうは/いい/てんきですね/。"今日はいい天気ですね。-ToArray解説ちょっと長めの関数ですが、ポイントはJapanesePhoneticAnalyzerクラスのGetWordsメソッドが返すJapanesePhonemeオブジェクトのIsPhraseStartプロパティです。IsPhraseStartプロパティは、当該単語(Phoneme)が文節(Phrase)の開始部分にあたる単語であればTrueを返します。JapanesePhonemeコレクションを文頭から文末まで列挙していったとき、IsPhraseStartプロパティがFalseからTrueに変わる部分が文節の境界になるわけです。Split-JpText関数では、単語を列挙していき、文頭もしくは文節の境界に遭遇すると、文節に含まれる文字列(Textプロパティ)とその読み(Yomiプロパティ)と単語の配列(Wordsプロパティ)を格納するオブジェクトを新たに作成し、$phrase変数に代入します。一方で$phrase変数に元々入っていたオブジェクトは、$phrases配列に追加します。$phraseオブジェクトのWordsプロパティには、列挙中の単語を都度、追加していきます。$phraseオブジェクトのTextプロパティとYomiプロパティはスクリプトプロパティとして定義しておき、必要時に値を取得するようにしてあります。まとめ3回に渡って、JapanesePhoneticAnalyzerクラスの使用法を具体的なラッパー関数を作成して紹介しました。個人的には、PowerShellからなら中編で挙げた、読みの取得が一番使いでがあるかな?と思いました。今回取り上げた分かち書きは、意外と応用例が思いつきませんでした。前編のGet-JpWord関数を使って、何らかの文書群の単語リストをあらかじめインデックスとして出力しておき、単語検索コマンドを実装するのも面白そうですね。残念ながら品詞情報が取れないので、JapanesePhoneticAnalyzerをmecabとかの形態素解析エンジンの代替にするのはちょっと厳しいかもしれないです。標準機能のみでちょっとしたものを作れるのは大きいかと思います。何か日本語の文章を解析する必要があるときには使ってみてはいかがでしょうか。|TweetC#6.0のnameof演算子(じんぐるさんによる解説、岩永さんによる解説)が羨ましかったので、PowerShellでも似たようなことができるようにしてみました。tree)を解析して、含まれる変数名やプロパティ名を抽出しています。鷲ノ巣という記事を見て、じゃあPSでコマンド(高度な関数)を書く時にも同じことが出来るといいかな?と思ったのがきっかけです。}}こういう風に、"Number"という文字列をコード中に書かずに、-Numberパラメータ指定の有無を確認できるようになる、というわけです。ようにすると、if文の中身が実行されます。)ただ作ってはみたものの、使う意味がどれほどあるのか疑問に思えてきました。一応、ISEでは変数名やメンバ名に入力補完が効くので、実際の変数名を文字列で手打ちしなくて済むというメリットはなきにしもあらず、ですか。動的言語なので、存在しない変数名やメンバ名を入れても実行前にエラーは出ないですからね。(Set-StrictModeによるストリクトモードは編集時ではなくあくまで実行時(正確には変数やメンバを参照した瞬間)にエラーを出すためのもの)それとISEのリファクタリング機能は弱い(というか無い)ので、リファクタリングに追従できるという本家nameof演算子に存在するメリットは、現状のところISEを使っている限りは享受できません。Analyzerによる静的解析を組み合わせればあるいは意味が出てくるのかもしれないですが、まだ確認できてないです。いうわけで、書いてはみたもののなんか微妙ですが、せっかくなんで公開しときます。|Tweetあけましておめでとうございます。2015年、直近の私のセッション予定について告知します。ご都合がよければ、ぜひぜひお越しくださいませ。(大阪会場)タイトル:「PowerShellスクリプトを書いてラクしよう」セッション概要:コンピューター上で定型作業を手動でちまちまやるのは効率が悪いです。スクリプトを書いて自動化しましょう。最近のWindowsにはPowerShellというステキな環境が最初から入っています。PowerShellはサーバー管理の自動化ツールとして重要ですが、本セッションではPowerShellでのスクリプトの書き方を、まずは身近なテーマの具体例を交えて伝授いたします。リリースされるv5.0の紹介もちょっとだけします。してセッションさせていただきます。今回のイベントのテーマとして、最新の技術をわかりやすく、初心者や学生に伝えるというのがあります。そこで私の方からは、初心に返って、本来PowerShellがターゲットとしているサーバーOSというよりかは、クライアントOSで日常的に使えそうなスクリプトを題材に、PowerShellの紹介をしていこうと思っています。Group大阪の主催者であるwakaさんによる「PowerShellで変わるサーバ構築と管理」というセッションもあります。こちらはPowerShellによるサーバー構築、管理のお話なので、どちらかというと本筋の話だと思います。Code(インフラ構成をコード記述により自動化する手法)が可能となりました。WindowsのみならずLinuxなど他プラットフォームについてもDSCで横断的に構成管理を行える世界が来ようとしています。5.0の新機能も交えて紹介したいと思います。ひとこと:オープンセミナー広島というIT系無料セミナーでセッションをさせていただくことになりました。AzureといったMicrosoft系サーバー、クラウド環境の構成管理のお話をします。これまでずっと、どちらかというとMicrosoft系のイベントばかりでセッションしてきたので、ちょっとドキドキしています。今回のイベントでは、Chef、Docker、Ansibleなど旬のお話が聞けるので私も勉強しにいこうと思っています。ご存じのとおり、Microsoftの昨今の戦略変更で、これからはMicrosoft技術のみならず、オープンソースのソフトウェアについてもちゃんと知っておかないといけませんし!2015/03/14(土)?イベント:わんくま同盟大阪勉強会タイトル:「未定」ひとこと:PowerShell関係で何かセッションをしようと思っています。2014の22日目の記事です。前回はMMLをパースし、音楽をBeepで再生するところまで作りました。MMLはテキストデータなので、テキストエディタで入力しても良いのですが、どうせなら、PowerShellでエディタも作ってしまいましょう。コードいきなりですが、エディタの本体コードを。$mml}使い方PowerShellコンソール上(ISEは不可)で、前回公開した、ConvertFrom-MML、Invoke-Beep、Invoke-Mmlの3つの関数をまず読み込み、続いて上記のEnter-MusicEditor関数を読み込みます。この状態でコンソール上でEnter-MusicEditorを実行すると、MMLエディタモードに入ります。MMLエディタモードでは、PCのキーボードを鍵盤代わりにして入力できます。Cキーを押下すると、「ド」の音がBeepで鳴り、コンソールに"C4"と出力されます。同様にFキー押下で「ド♯」が鳴り"C+4"と出力されます。どのキーがどの音に対応しているかは、上記コードの$keyMap変数に格納された連想配列を参照してください。(なんとなくですけど、楽器の鍵盤の配置と合わせてあります)Backspaceキーを押下すると、直前の入力を削除できます。EnterキーかEscapeキーを押下すると、エディタモードを終了します。出力したMMLは、コンソール上に表示が残るので、あとはコピーしてInvoke-Mml関数に渡してやると演奏することができます。$mml=Enter-MusicEditorとしてやると、入力したMMLをそのまま変数に格納できます。$mmlと実行すれば演奏できます。技術的には全然大したことをしてないですが、一応解説。[System.Console]::ReadKey()で入力したキーコードを判別します。引数に$trueを指定すると、入力したキー名をそのままコンソールに出力するのを抑制できます。ReadKeyメソッドはConsoleKeyInfoオブジェクトを返します。アルファベットキーについてはKeyCharプロパティの値、特殊キーについてはConsoleKey列挙体を返すKeyプロパティの値で調べることができます。あとは入力キーから対応する音名を連想配列$keyMapから取ってきて、その音名を[System.Console]::Write()でコンソール出力すると同時に、Invoke-Mml関数でその音をBeepとして鳴らしているだけです。いや、やはり無理があるか...。他のMMLコンパイラと併用して、ちょっと演奏しながらMML入力したいな、というときにもしかすると役に立つかもしれません。機能が少なすぎるんで、せめて↑で半音上げ↓で半音下げ、→で伸ばす←で短く、くらいはそのうち実装してみたいですね。MML作成にはあんまり役に立たないかもしれませんが、PowerShellでコンソールの入出力を制御するのは、こういう単純なものなら意外と簡単にできるという、サンプルにはなるかと思います。2014の11日目の記事です。Languageの略で、その名の通り音楽演奏データを記述するための言語です。BASICのPLAY文で使うあれです。MIDIファイルに変換するコンパイラもありましたよね。「ねこふんじゃった」の最初の部分をMMLで書くとこんな感じです。MMLはいろんな記法があるのですが、よくあるのはこういうのです。e-d-<g-4>g-rg-4e-d-<g-4>g-rg-4e-d-<g-4>g-4<e-4>g-4<d-4>frf4e-d-<d-4>frf4e-d-<d-4>frf4e-d-<d-4>f4<e-4>f4<g-4>g-rg-4ドの音をc、レの音をd、のように以下シの音をbまでアルファベット音階で割り当てます。半音上げる(シャープ)場合は音名のあとに+、半音下げる(フラット)場合は-を付与します。音の長さは4分音符なら4、8分音符なら8と書きます。付点は数字のあとに.を付けます。数字省略時は8分音符と解釈するのが普通のようです。オクターブを上げる場合は>、下げる場合は<と書きます(コンパイラによっては逆の解釈をする)。本物のMMLでは、音色の指定だとかトラックの割り当てだとか、もっとたくさん命令があるんですが、基本はだいたいこんなもんです。PowerShellで音を鳴らすにはPowerShellで音を鳴らすには、.NETのSystem.Console.Beepメソッドを使うのが一番手っ取り早いです。比較的古いWindowsではハードウェアのビープスピーカーから、比較的新しいWindowsではサウンドデバイス上で鳴ります。今回のMMLシーケンサーも結局はBeepメソッドです。ぎたぱそ先生がずっと以前に書いておられます。今回のはまあ、MMLシーケンサー部分を除けば二番煎じなんですけどもね。PlayerをCOM経由で実行する方法や.NET(WPF)のSystem.Windows.Media.MediaPlayerクラスを使う方法などがあります。音程の決め方Beepメソッドでは第1引数にビープ音の周波数をHzで、第2引数に再生時間をミリ秒で指定します。音程(音の高さ)はHzで指定する必要があります。ここでドの音は何ヘルツで、みたいな対応表をどこかから探してきてそのデータを使ってもいいんですが、今回はせっかくなので、PowerShellで計算して求めてみます。ある音程の一つ上のオクターブの音程の間の周波数比は、1:2です。ピアノ等の鍵盤楽器が近くにあれば、それを見てもらえば分かると思いますが、1オクターブには12の音程が含まれています。1オクターブの周波数比を12個均等に分割します(この周波数の決め方を平均律といいます)。隣り合う音程の周波数比は、1:12√2となるわけです。音程の周波数比はこれでわかりました。あとは基準となる音の周波数が分かれば、全ての音の周波数が計算できるわけです。時代や地域、演奏する楽器等によって微妙に違ってきますが、現代日本においては普通は、A(ラ)=440Hzが基準周波数です。あとは単純にかけ算して周波数を求めて連想配列に入れておくだけです。コードにすればこんな感じですね。1/12)をかけ、-で半音下がる場合は割ればいいだけです。音価というのは音の長さです。Beepメソッドの第2引数にはミリ秒で実際の時間を指定する必要があるので、これも計算で求めてやります。4分音符というのは、1小節(全音符)を4分割、つまり1/4した音価を持ちます。同様に8分音符は1/8ですね。付点がつくと音価は1.5倍になります。4分音符の具体的な音価はどうやって定めるのでしょうか。それを決めるのがテンポと拍子です。Minuteともいう)で定義されます。今回作るシーケンサーは4/4拍子、すなわち1拍=4分音符とする4拍子固定とするので、1分間に4分音符がBPM回含まれることになります。具体的なコードは...略します。単なるかけ算と割り算だけなんで。MMLのパースえっと時間がなくなってきたので、駆け足で説明します。MMLのパースとは、要するに最初の例のようなMML(テキストデータ)から、実際に演奏する音程と音価の組み合わせのデータとして組み立てる作業になります。今回のシーケンサーでは、繰り返し記号等はサポートしないので、単にMMLを一文字ずつ読み込んで、音名(cなど)を見つけたら、その後の文字を読んで、+があれば半音上げるなどして周波数を求め、その後に数字があればn分音符とみなし、先ほどの計算式から実際の音価を求めてやる。いうのを全部の音でくり返すだけです。この処理をやっているのがConvertFrom-MMLという関数です。MMLテキストを入力してやると、周波数(Frequency)や発音時間(Duration)などをプロパティとして含んだpscustomobject(Noteオブジェクト)を出力します。(Noteとは音符のことです)MMLの演奏パースしたMMLを実際に演奏するのがInvoke-Beep関数です。入力は、ConvertFrom-MMLで生成したNoteオブジェクトです。$note.Duration)するだけです(えー)。あ、あと休符の時はDuration分だけSleepを入れてやっています。MMLの>と<の意味を逆転する-Reverseスイッチ、BPMを指定する-Bpmパラメータ(デフォルト120)なんかも用意してます。実際にはMMLから直接演奏できるように、Invoke-Mmlというラッパー関数を用意しています。冒頭のねこふんじゃったのMMLを再生するにはこんな感じにします。@PSBoundParameters|Invoke-Beep}おわりに今回はMMLをパースしてBeepを演奏するスクリプトをPowerShellで作ってみました。これをシーケンサーというのはおこがましいと思いますが、まあたまにはこういう柔らかいネタもいいんじゃないでしょうか。ドレミの音がどうやって決められてるのかというのも、もしかして話のネタくらいにはなるかも。これ、シーケンサーといいつつ、入力機能がないですよね。それについては次回やります。PowerShellアドベントカレンダー2014はまだまだ残席ございます。あなたのPowerShell話を聞かせて下さい。2014の1日目の記事です。5.0について、そろそろ情報が出回ってきました。Previewに同梱のもので試すことができます。v5での新機能、改善点は多岐に上ります。詳しくは、リリースノートが一番充実しているかと思います。日本語だとぎたぱそ氏の記事がまとまっているかと思ます。ここまで挙げた新機能や改善点は、とても順当でまっとうな進化点なのですが、v5にはちょっと異彩を放つ新機能がしれっと追加されています。CSV、JSON、XMLのような既知のフォーマットではないが、何らかの法則性のあるテキストデータがあるとします。そんなテキストデータは(不幸なことに)割と世の中にあふれていますが、そのままでは(人が読む以外には)利用できないので、データとして扱うには、解析し、レコード(プロパティ:プロパティ値)として再構築する必要があります。フォーマットが既知のものではないため、既存のパーサーを使って解析することはできません。従来のアプローチだと、このようなデータに対しては、まずユーザー(人間)がデータの法則性を読み取り、その法則をコンピュータに分かる表現(コードや正規表現など)に変換してやる必要がありました。事前にユーザーがテキストデータの一部分のみを取り出し、各項目に対してプロパティ名を指示したデータ(テンプレート)を用意しておくと、元のテキストデータとユーザーが用意したテンプレートから法則性を解析し、元のテキストデータ全体を自動的にテキストデータからオブジェクトに変換してくれる機能です。コマンドレット(ConvertFrom-String)による実装になります。