HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2020
0226
こいる指定箇所だけ改行を削除する8解決


こいる

リンク

2020/2/26(Wed) 19:01:53|NO.89561

指定箇所だけ改行を削除したいです。
どうすればできますか?



この記事に返信する


あらや

リンク

2020/2/26(Wed) 20:52:29|NO.89562

notegetで改行の前後の文字列を両方取得

notedelで改行の後の行を削除

noteaddで改行の前の行に取得した2行を合成して上書きモードで追加

こんな感じの流れで出来るのではないでしょうか。



ほかにもpeekとpokeなどを使用して
改行の次の文字を1つずつ前に詰めていくという方法、

memcpyを使用する方法などでも可能だと思います。



こいる

リンク

2020/2/26(Wed) 21:40:53|NO.89563

返信ありがとうございます。
書いてる通りにするとできました!

#define newLineIndex 1;削除する改行のインデックス(行) buf = "あいうえお"+"\nかきくけこ" mesbox buf, ginfo_winx,300 notesel buf wait 100; 1秒後 // notegetで改行の前後の文字列を両方取得 sdim sIndex,,1 noteget sIndex(0) ,newLineIndex-1; 前 noteget sIndex(1) ,newLineIndex; 後 // notedelで改行の後の行を削除 notedel newLineIndex // noteaddで改行の前の行に取得した2行を合成して上書きモードで追加 noteadd sIndex(0) + sIndex(1) , newLineIndex-1 ,1 mes "完了" // mexbox更新 objprm 0,buf

しかし、個人的には、もう少しスタイリッシュにしたいです。
peekとpokeを使う方法や、memcpyを使う方法も教えていただけませんか?



あらや

リンク

2020/2/26(Wed) 22:28:25|NO.89564

先述の3パターンをモジュールにしてみました。

peekとpoke、memcpyのやり方はどこに改行があるかを特定しなければいけないという点で
どちらにも共通するので、準備段階の処理は同じになります。


#module // 指定した改行の削除(メモリーノートパッド版) #deffunc delCRLF_1 var buf, int p1 notesel buf; src1 = ""; src2 = ""; noteget src1, p1-1; noteget src2, p1; notedel p1; noteadd src1+src2, p1-1, 1; return; // 指定した番号(何番目か)の改行のインデックスを返す #defcfunc _searchCRLF var buf, int p1 _idx = 0; repeat p1 _idx += instr(buf, _idx, "\n") + 2; loop return _idx-2; // 指定した改行の削除(peek&poke版) #deffunc delCRLF_2 var buf, int p1 buflen = strlen(buf); idx = _searchCRLF(buf, p1); repeat buflen-idx poke buf, idx+cnt, peek(buf, idx+cnt+2); loop return; // 指定した改行の削除(memcpy版) #deffunc delCRLF_3 var buf, int p1 buflen = strlen(buf); idx = _searchCRLF(buf, p1); memcpy buf, buf, buflen-idx, idx, idx+2; return; #global // テスト用文字列 buf = {" あいうえお かきくけこ さしすせそ たちつてと なにぬねの"}; pos 0, 0; mes "元の文字列\n\n"+buf; // メモリーノートパッド形式 buf2 = buf; // 元の文字列をコピー delCRLF_1 buf2, 2; pos 320, 0; mes "メモリーノートパッドで2番目の改行削除\n\n"+buf2; // peek&poke形式 buf2 = buf; // 元の文字列をコピー delCRLF_2 buf2, 3; pos 0, 240; mes "peek&pokeで3番目の改行削除\n\n"+buf2; // memcpy形式 buf2 = buf; // 元の文字列をコピー delCRLF_3 buf2, 4; pos 320, 240; mes "memcpyで4番目の改行削除\n\n"+buf2;



あらや

リンク

2020/2/26(Wed) 22:34:43|NO.89565

補足です

全ての改行を削除する場合ならばstrtrimやstrrepの方が手っ取り早いです。



こいる

リンク

2020/2/27(Thu) 10:57:28|NO.89566

モジュールありがとうございます。

peek&pokeは、改行とばして文字列を全てずらしているのでしょうか?
そのせいか、他と比べて格段に処理速度が遅いですね。
特に文字列が長くなると、めちゃめちゃ遅いです。

memcpyは、メモリオフセットを使って、改行をすっとばしたのを上書きしているのでしょうか?
メモリーノートパッド式より処理は高速ですが、
削除するインデックスが大きくなると、
メモリーノートパッド式より遅くなるみたいですね。


総合した速さでは、メモリーノートパッド式が一番な気がします。
しかし、必ず、最後に空行がついちゃいますね。
しかも、一番最後の空行が削除できないです。


ですので、それなりに高速で、最後の空行も削除できる、memcpy式が一番いいです。


>全ての改行を削除する場合ならばstrtrimやstrrepの方が手っ取り早いです。
タイトル通り、指定箇所だけ改行を削除したいので、その方法は必要ないです。
お気遣いありがとうございます。


しかし、こんな方法があるなんて思いもしなかったです。
ずっと、指定インデックスにある改行コードを直接削除する方法を探していました。

本当に助かりました。ありがとうございました!



とあるプログラマ

リンク

2020/2/27(Thu) 11:41:22|NO.89567

解決済みのようですが、正規表現なら1つの関数だけでできてしまいます…


#include "mod_regexp.as" string = {"あいうえお かきくけこ さしすせそ たちつてと なにぬねの はひふへほ まみむめも やゆよ わをん"} input LineIndex, 50, 20 pos 50, 0 mes "行目とその次の行の間の改行を削除" pos 0, 20 objsize 50, 20 button gosub "実行", *execute pos 0, 50 mes "原文" mes mes string stop *execute // ************************** // 正規表現で置き換え // // (?:hoge) : サブマッチに含めないグループ // ^ : 行頭を意味する // . : 任意の一文字 // * : 0文字以上の繰り返し // *? : 最短検索 (例えば ABCABC という文字列で A.*B と検索したら ABCAB になるが A.*?B だと AB がヒットする) // \\r : 改行(CR) // \\n : 改行(LF) Windowsの場合の改行コードはCR+LFが主流 // {0} : 指定回数の繰り返し // // // やってること // // 検索対象の指定↓ ↓改行が来るまでの任意の文字の繰り返し ↓対象の改行を消すのでサブマッチから除外する // string2 = replace(string, "^((?:.*?\\r\\n){" + (LineIndex - 1) + "}.*?)\\r\\n", "$1", 0, 1, 1) // 文字列の始まり(行頭)↑ 繰り返し回数の指定↑ ↑改行を消す直前の行 ↑最初にマッチしたものだけを置き換えないと置き換えの連鎖が起こる // (指定の改行の直前を含まないので1引く) 全体を1行と見なす場合は0でも大丈夫? // // ************************** string2 = replace(string, "^((?:.*?\\r\\n){" + (LineIndex - 1) + "}.*?)\\r\\n", "$1", 0, 1, 1) color 255, 255, 255 boxf ginfo_winx / 2, 50 color pos ginfo_winx / 2, 50 mes "置き換え後" mes mes string2 return



あらや

リンク

2020/2/27(Thu) 19:58:24|NO.89571

>peek&pokeは、改行とばして文字列を全てずらしているのでしょうか?
その通りです。
1つずつ前にずらすというか、正確には1バイトずつコピペする感じなので
非常に低速になってしまいます。

>memcpyは、メモリオフセットを使って、改行をすっとばしたのを上書きしているのでしょうか?
こちらもそういう事です。
改行以降を全て範囲選択して改行の上にコピペする感じでしょうか。
そのために選択する範囲が大きくなるほど遅くなってしまいますね。

>総合した速さでは、メモリーノートパッド式が一番な気がします。
>しかし、必ず、最後に空行がついちゃいますね。
>しかも、一番最後の空行が削除できないです。
メモリーノートパッドを使ったからと言って、
ほかの文字操作が使えない訳ではありません。

メモリーノートパッドの処理が終わったあとに

lpoke buf, strlen(buf)-2, 0;
このように末尾の2バイトを0にすれば改行を消すことが出来ます。

スタイリッシュではないかもしれませんが、
複数行で部分的な処理をするのならば
メモリーノートパッドが一番安定した速さになるかと思います。


とあるプログラマさんの正規表現が一番スタイリッシュかもしれませんが、
どれを選ぶのかは好みの問題にもなるので、私の3パターンは
こんなやり方もあるという程度に参考にしていただければと思います。



こいる

リンク

2020/2/28(Fri) 13:02:53|NO.89572

>とあるプログラマさん
正規表現でこんなことができるんですね。
自分にはいまいち仕組みが分からないですが……。


>あらやさん
なるほど、勉強になりました。

ありがとうございました。



ONION software Copyright 1997-2023(c) All rights reserved.