Ticket #22781Open Date: 2010-08-09 12:01 Last Update: 2010-08-31 13:57 文字列操作コマンド:文字列の挿入
Attach FileTicket History - 3/62 Histories [Show all old Histories]2010-08-09 12:01 Update by: ku9292
Commentyutakapon への返信
ご興味を持って頂きありがとうございます! 仕様ですが、strconcatと同じく、ターゲットの文字列型変数をはじめに記述するコマンド書式ではどうでしょうか? --- strinsert 文字列を挿入する。 形式 strinsert <strvar> <pos> <string> 解説 文字列変数 <strvar> の <pos> 文字目の直前に文字列 <string> を挿入する。 例 ; varstrの10文字目の直前にバージョン番号を挿入する。 varstr='Tera Term is released.' strinsert varstr 10 ' 4.67' ●実装ついでに、削除の機能もあると面白いです。 strdelete 文字列を削除する。 形式 strdelete <strvar> <pos> <len> 解説 文字列変数 <strvar> の <pos> 文字目から <len> 文字分を削除し詰める。 例 ; varstrの4文字目から3文字を削除し詰める。 varstr='abcdefghi' strdelete varstr 4 3 Commentku9292 への返信
「文字目」のオリジンはどうなりますか? 0 or 1? また、文字目が1オリジンだった場合、「1文字目」が指定されたり、<strvar>の 最後の文字目が指定された場合は、どういう扱いになるでしょうか?
この例では、varstrの結果は以下になることが期待値ですか? 'Tera Term4.67 is released.'
この場合の期待値を教えてください。 Commentstrvar の長さを超える値、あるいはマイナスの値が pos に指定されたらどうなりますか? Comment>「文字目」のオリジンはどうなりますか? 0 or 1? また、文字目が1オリジンだった場合、「1文字目」が指定されたり、<strvar>の最後の文字目が指定された場合は、どういう扱いになるでしょうか? strvarの先頭の文字を1文字目として数えることを想定していました。 varstr='Tera Term is released.' varstrの10文字目は空白なので、10文字目の直前(9文字目=mの直後)に' 4.67'を挿入するので、元々10文字目だった空白は、' 4.67'の後に順送りに移動されて、 'Tera Term 4.67 is released.' となることを期待していました。 また、<pos>で1文字目が指定された場合には、strvarの1文字目の直前に挿入されるので、strvarには先頭から挿入された文字が入り、続いて元々の文字が続きます。 ●しかし、これだとstrconcatと同じ機能、つまり、<strvar>の最後の文字目の後に挿入(追加)することができないですね。この場合は考えていませんでした。浅はかでした。 そこで、<pos>は文字目の後として扱い、strvarの先頭の文字は1とする。先頭の文字の前に挿入する場合は便宜上0を指定する。末尾の後に追加するときは、最後の文字目を指定する。文字列の中間では、たとえば、'12345'の2文字目に'abc'を挿入すると、'12abc345'になるとすると、うまくいくでしょうか? 削除は、strvarの先頭の文字を1として、指定した文字数を削除し詰めるというのではだめでしょうか?(挿入とは整合性がなくなりますが) '12345'の先頭から2文字削除 pos=1 len=2 →345 '12345'の3文字目から3文字削除 pos=3 len=3 →12 # ともかくも、実装しやすい方法で構いませんので、、、 宜しくお願い致します。 CommentNone への返信
想定していませんでした。 strcopyで調べてみると、 ・posがマイナスだと、1と解釈される ・posがstrvarの長さを超えると、処理されない ・lenがマイナスだと、処理されない ・lenがstrvarの長さを超えると、strvarの長さの範囲で処理される となっているので、同様に、 ・posがマイナスだと、0と解釈される(先頭に挿入) ・posがstrvarの長さを超えると、処理されない ということではどうでしょうか? 宜しくお願い致します。 CommentNone への返信
2010-08-09 23:20 更新者: Noneは、私が更新しました。 Comment以下のような仕様でいかがでしょうか? --- strinsert 文字列を挿入する。 形式 strinsert <strvar> <index> <string> 解説 文字列変数 <strvar> の <index> 位置(0オリジン)に、文字列 <string> を挿入する。 例 ; strinsert 'abc' 2 'XYZ' -> 'abXYZc' strinsert 'abc' 0 'XYZ' -> 'XYZabc' strinsert 'abc' -1 'XYZ' -> シンタックスエラー strinsert 'abc' 3 'XYZ' -> 'abcXYZ' strinsert 'abc' 4 'XYZ' -> シンタックスエラー 形式 strremove <strvar> <index> <len> 解説 文字列変数 <strvar> の <index> 位置(0オリジン)から <len> 文字分を削除し詰める。 例 ; strremove '123abc456' 3 3 -> '123456' strremove '123abc456' 0 3 -> 'abc456' strremove '123abc456' -1 3 -> シンタックスエラー strremove '123abc456' 8 1 -> '123abc45' strremove '123abc456' 8 2 -> シンタックスエラー strremove '123abc456' 9 1 -> シンタックスエラー strremove '123abc456' 3 0 -> シンタックスエラー CommentCommentstrscan や strmatch では 1 オリジンなのですが、それにあわせたほうがよくないですか? Commentでは、以下のようにしましょうか。 --- strinsert 文字列を挿入する。 形式 strinsert <strvar> <index> <string> 解説 文字列変数 <strvar> の <index> 位置(1オリジン)に、文字列 <string> を挿入する。 例 ; strinsert 'abc' 3 'XYZ' -> 'abXYZc' strinsert 'abc' 1 'XYZ' -> 'XYZabc' strinsert 'abc' -1 'XYZ' -> シンタックスエラー strinsert 'abc' 0 'XYZ' -> シンタックスエラー strinsert 'abc' 4 'XYZ' -> 'abcXYZ' strinsert 'abc' 5 'XYZ' -> シンタックスエラー 形式 strremove <strvar> <index> <len> 解説 文字列変数 <strvar> の <index> 位置(1オリジン)から <len> 文字分を削除し詰める。 例 ; strremove '123abc456' 4 3 -> '123456' strremove '123abc456' 1 3 -> 'abc456' strremove '123abc456' -1 3 -> シンタックスエラー strremove '123abc456' 0 3 -> シンタックスエラー strremove '123abc456' 9 1 -> '123abc45' strremove '123abc456' 9 2 -> シンタックスエラー strremove '123abc456' 10 1 -> シンタックスエラー strremove '123abc456' 4 0 -> シンタックスエラー Comment1オリジンにすると、統一性があっていいですね! そもそも、<index>位置に挿入するという扱いだと、1オリジンで良かったのでした。 既存の文字の「前か後か」という感覚に拘泥していました。。。 混乱させてすみません。>yutakapon様 宜しくお願い致します。 Commentku9292 への返信
早速ですが、strinsertとstrremoveを実装してみました。評価願います。 時間がなかったので、まだドキュメントはありません。 http://ttssh2.sourceforge.jp/snapshot/snapshot-20100811.zip 一応、以下のサンプルコードで確認はしました。 s = '123abc456' strremove s 4 3 ;-> '123456' messagebox s s s = '123abc456' strremove s 1 3 ;-> 'abc456' messagebox s s s = '123abc456' strremove s -1 3 ;-> シンタックスエラー messagebox s s s = '123abc456' strremove s 0 3 ;-> シンタックスエラー messagebox s s s = '123abc456' strremove s 9 1 ;-> '123abc45' messagebox s s s = '123abc456' strremove s 9 2 ;-> シンタックスエラー messagebox s s s = '123abc456' strremove s 10 1 ;-> シンタックスエラー messagebox s s s = '123abc456' strremove s 4 0 ;-> シンタックスエラー messagebox s s end s='abc' strinsert s 3 'XYZ' ;-> 'abXYZc' messagebox s s s='abc' strinsert s 1 'XYZ' ;-> 'XYZabc' messagebox s s s='abc' strinsert s -1 'XYZ' ;-> シンタックスエラー messagebox s s s='abc' strinsert s 0 'XYZ' ;-> シンタックスエラー messagebox s s s='abc' strinsert s 4 'XYZ' ;-> 'abcXYZ' messagebox s s s='abc' strinsert s 5 'XYZ' ;-> シンタックスエラー messagebox s s Commentyutakapon への返信
早速の実装をありがとうございます。 早速、こちらでもサンプルコードと本来やりたかった処理でも試してみました。 大丈夫でした。(無論ですね!) # 本来やりたかった処理とは、たとえば、数字を含む文字列を正規表現で合致させて、 # 頭に0を補って数字の桁数を統一したり、頭の0を削除したりという処理です。 # これらをすっきりマクロで記述することができるようになり助かりました。 Commentku9292 への返信
早速の評価ありがとうございます。ドキュメントも記載しておきます。 余力があれば、.NET FrameworkのStringメソッドにあるような機能をさらにサポートしてみたいと 思ってます。何かご希望はありますか? http://msdn.microsoft.com/ja-jp/library/7wtc81z6%28v=VS.80%29.aspx Commentyutakapon への返信
そうですね~、まずはReplaceメソッドがほしいです。 これが実装されると、正規表現で合致させて、挿入、削除、そして“置換”ができるのでとても嬉しいです。 宜しくお願い致します。
Commentku9292 への返信
strreplaceコマンドを実装してみました。 http://ttssh2.sourceforge.jp/snapshot/snapshot-20100811_2.zip strmatchと組み合わせた時のサンプルコードは、以下のようになります。 ドキュメントもご覧ください。 src='Microsoft Windows XP [Version 5.1.2600]' strmatch src '(Version \d+.\d+.)\d+' int2str s result messagebox s groupmatchstr1 pos=result ; 23 mstr=groupmatchstr1 ; Version 5.1. strreplace src pos mstr 'Build ' if result=1 then messagebox src 'result' ; Microsoft Windows XP [Build 2600] endif Commentyutakapon への返信
早速、strreplaceを動かしてみました。ばっちりです! また、HELPドキュメントも拝見しました。 これで、いままで、無理くり書いていた部分のコードが、 とても簡潔に書き直せます。 どうもありがとうございました。 Commentku9292 への返信
確認していただき、ありがとうございます。 他にも文字列操作系でほしい機能はありますか? 次のリリースに向け、内部の締めが 8/23 なので、それまでで対応できる ものならば、サポートを検討します。 Commentyutakapon への返信
はい。文字列操作系の機能は、当分使いそうもないものまであったりすると、いつかは便利になることがあるのでしょうが。。。 まず、自分で使いそうなところとしては、String.Trimでしょうか。 あと、String.SpritとString.Joinもあれば(とても)便利だと思います。teratermマクロでは配列が使えないので、代替として予約変数1~9で対応することになりましょうか? Commentku9292 への返信
そもそも、strreplace で正規表現が指定できるようにすれば、よいのでした。 ということで、以下のアーカイブで正規表現に対応させてみました。 使ってみてください。 http://ttssh2.sourceforge.jp/snapshot/snapshot-20100814.zip ドキュメント: http://ttssh2.sourceforge.jp/manual/ja/macro/command/strreplace.html CommentNone への返信
書式としては、こんな感じでしょうか? strtrim <strvar> <trimchars>
そうですね。「配列」そのもののサポート要望は、以前から出てはいるのですが、まだ実装までは 至っていないです。 予約変数1~9で対応するとした場合、どのような書式になるでしょうか? Commentyutakapon への返信
仕様拡張をありがとうございます。これで元々期待していた機能が実装されたことになります。ちょっと使い込んでみますね! Commentyutakapon への返信
はい。これでよろしいと思います。
予約変数はparam1~param9を使うとして、一案としてこのような感じになりましょうか。 strsplit 文字列から部分文字列を取り出す 形式 strsplit <strvar> <splitter> <intvar> 解説 文字列 <strvar> から区切り記号 <splitter> で区切られた部分文字列を取り出してparam1~param9に返す。 <intvar> には、取得する部分文字列の最大数(9以下)を指定する。 文字列中の部分文字列の数が <intvar> 未満であるとき、部分文字列が代入されなかったparamには、 NULLが代入される。 strsplit "Sun,Mon,Tue,Wed,Thu,Fri,Sat" "," 7 messagebox param1 "parm1" messagebox param2 "parm2" messagebox param3 "parm3" messagebox param4 "parm4" messagebox param5 "parm5" messagebox param6 "parm6" messagebox param7 "parm7" strjoin 部分文字列を連結し文字列にする 形式 strjoin <strvar> <splitter> <intvar> 解説 param1~param9の部分文字列を区切り記号 <splitter>で連結し文字列 <strvar> を返す。 <intvar> には、連結するparamの数(9以下)を指定する。 param1="Jan" param2="Feb" param3="Mar" param4="Apr" param5="May" param6="Jun" strjoin strvar "," 6 messagebox strvar "strvar" よろしくお願い致します。 Commentku9292 への返信
早速作ってみました。何か問題あれば、連絡願います。 Commentku9292 への返信
strsplit を実装しました。 "param1"は予約済み変数であり、ユーザからは使えないようですので、代わりに"groupmatchstr"を 使うようにしました。 http://ttssh2.sourceforge.jp/snapshot/snapshot-20100816.zip http://ttssh2.sourceforge.jp/manual/ja/macro/command/strsplit.html Commentyutakapon への返信
早速の実装をありがとうございます。 src='Sun,Mon,TueThu,Fri,Sat' strsplit src ',' 7 のように、separatorで区切られた部分文字列がNULLの場合には、 該当する順番のgroupmatchstrNには、次の部分文字列が前詰めされて代入されます。 この事例ではgroupmatchstr4にはThuが代入されます。 CSVファイルの処理等、部分文字列の順番が意味を持つときには、 該当するgroupmatchstrNにはNULLが代入されるほうが都合が良いと思いますが、 如何でしょうか? Commentyutakapon への返信
ありがとうございます。 先頭、末尾にタブ又は空白が含まれそれを削除したい場合には、 エディタでtrimcharsにタブ又は空白を代入しておけば正常に処理されますが、 実装して頂いたstrsplitと同様にspecialとの併用で、 trimchars="\t " と記述できるように拡張すると、より便利だと思うのですが。 よろしくお願い致します。 Commentku9292 への返信
調査の結果、strtok_s()の仕様でした。 実装を工夫すれば、途中に、区切り文字が連続した場合でも対処できそうです。 ところが、これも strtok_s()の仕様なのですが、先頭に区切り文字が来ると、無視されてしまいます。 これはどうなるのが期待値ですか? ,Sun,Mon,Tue,Thu,Fri,Sat, Commentyutakapon への返信
僕の個人的な想いとしては、 groupmatchstr1="" groupmatchstr2="" groupmatchstr3="" groupmatchstr4="Sun" groupmatchstr5="Mon" groupmatchstr6="Tue" groupmatchstr7="" groupmatchstr8="" groupmatchstr9="Thu" と、上の行を1レコードにしたCSVファイルを作り、それを普通にExcelで読み込んだときの動作を期待しています。 補足) groupmatchstrの数は、現状9が上限ですが、部分文字列が多い行をマクロで処理しようとすると不足するかもですね。 文字列の文字数の上限が255文字なので、そう多くの数は必要ないと思われますが、9個は微妙なところかも知れません。 Commentku9292 への返信 strsplitとstrtimを改修し、snapshot-20100816_2.zip でアップロードしました。 strsplitでは、連続した区切り文字を1つずつ区別するようにしましたが、代わりに 区切り文字には1つのみしか指定できないようになっています。 2010-08-16 23:42 Update by: |
Comment
なかなか面白そうなコマンドですね。 具体的な仕様はどのようにしましょうか? 例を提示してもらえれば、参考にします。