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


HSPTV!掲示板


未解決 解決 停止 削除要請

2006
1008
うひょ文字列を逆から検索するには11解決


うひょ

リンク

2006/10/8(Sun) 21:56:41|NO.2891

文字列で書かれた式を計算して数値で返す関数を作ろうと思い、作っているのですが、
括弧があったとき、その括弧の終わりを取得するのに一番外側の閉じ括弧を
取得するには逆から検索すればいいと思ったのですが、instrではそのようなことは
できないようで、困っています。
誰か、逆から文字列を検索するいい方法を知っている方は教えてください。
ちなみに、括弧の中の括弧は最後から2番目の閉じ括弧を取得しなければならない、
などは考えなくてもいいです。
よろしくお願いします。



この記事に返信する


kz3

リンク

2006/10/9(Mon) 13:04:55|NO.2900

# いつも考え方優先でごめんなさいね。

>文字列で書かれた式を計算して数値で返す関数を作ろうと思い、作っているのですが、
>括弧があったとき、その括弧の終わりを取得するのに一番外側の閉じ括弧を取得するには逆から検索すればいいと思ったのですが、
>instrではそのようなことはできないようで、困っています。
>誰か、逆から文字列を検索するいい方法を知っている方は教えてください。
>ちなみに、括弧の中の括弧は最後から2番目の閉じ括弧を取得しなければならない、などは考えなくてもいいです。

# 最初にレスする人は全文引用してみたり...

まず、
>括弧の中の括弧は最後から2番目の閉じ括弧を取得しなければならない、などは考えなくてもいいです。
というのは括弧の整合性は考えなくてもいいということですね。
# 何故考えなくてもいいのか分からないけど

>括弧があったとき、その括弧の終わりを取得するのに一番外側の閉じ括弧を取得するには逆から検索すればいいと思った
整合性は考えなくてもいいということなのに、
>括弧があったとき、その括弧の終わりを取得する

『その括弧の終り』とはつまり、括弧に対応する『閉じ括弧』のことではないのですか?
例:( 1 + 3))*4 ; 一番外側の閉じ括弧は入力ミス

まぁ考えないといっているので考えないようにして...
こういうのは大抵、全角半角混在の文字列とか考えたりするものですが、
それが難しければ、半角のみの文字列から考えるといいですよ。

>instrではそのようなことはできないようで、困っています。
そうですね。instrは左から右に検索していきますね。

でも検索開始位置をパラメータで指定できますよね?
検索開始位置を右から左に変えていけば、右から左に検索しているように見えますよね?

あくまで『文字列の後ろから前に検索』といっても、
"Hot Soup Processor"のなかから"Soup"を探すのに、「"puoS"はあるかなー」なんてことは、普通はしません。
# Hot Soup Processor
# Soup <-- 後ろから検索を始めて # Hot Soup Processor # Soup <-- ぴったんこ
これを元に、
# (1+1)*4
# ) <-- 後ろから検索を始めて から # (1+1)*4 # ) <-- ぴったんこ
という感じで考えてみてください。



774

リンク

2006/10/9(Mon) 18:12:34|NO.2909

質問がよくわからないけど、とにかく検索できればいいんだよね

検索する文字列が入ってる文字列に、全角文字が入ってなくて、
検索する文字列が1文字だけの場合、repeat+peekで
(そうでない場合、ちょっと面倒になるけど

あとは、repeat+instrで
-1が返ってくるようになってからの前回ヒットした位置とか、
ヒットした位置を全部配列にいれてしまうって手もあるね



男性A

リンク

2006/10/9(Mon) 19:02:21|NO.2910

計算式でのカッコに限った話なら
peekで取得した値が'('なら変数Iに1ずつ足して、')'なら変数Iから1ずつ引いていき、最初の"("以降でI=0になれば終了っていう考えかたもありますね。



Irisawa

リンク

2006/10/9(Mon) 22:17:36|NO.2913

strmid関数のように-1で右から検索できないかな〜と考えてみたのですが実際にやって
みると出来ませんでした。(^^ゞ
これは標準実装されていた方がいいかもしれませんね。
(kz3さんの云うように構文解析時の括弧の整合性チェックはそのままではできませんが)

Cランタイムライブラリを見るとstrtokというトークン分解関数があるようです。

http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/vclib/html/_crt_strtok.2c_.wcstok.2c_._mbstok.asp


#module #uselib "msvcrt.dll" #cfunc _mbstok "_mbstok" sptr, sptr ; トークンを配列分解 #deffunc GetToken array v1, str s1, str s2, local v2, local token sdim v1 v2 = 0 token = _mbstok(s1, s2) while token v1(v2) = strf("%s", token) token = _mbstok(0, s2) v2++ wend return ; トークンを無視して結合 #defcfunc GetTokenCpy str s1, str s2, local v1, local v2, local token GetToken token, s1, s2 sdim v1 foreach token v1 += token(cnt) loop return v1 #global string = GetTokenCpy("5 * (4 / (3 + 2) - 1)", " ") GetToken token, string, "()" foreach token mes token(cnt) loop stop

トークン分解は出来ますが、利用するのは少し面倒かも知れません。
(上記は計算するところまでなんとか作ろうとしたけど面倒で挫折した (^_^; )



七次元

リンク

2006/10/10(Tue) 13:37:45|NO.2917

昔自分が使ってたやり方です。

hoge = "(hoge(hoge)hoge)hoge" repeat res = instr(hoge,ind,")") if res==-1:break ind += res+1 loop mes "最後の閉じ括弧は"+ind+"byte目です"
繰り返し閉じ括弧を検索して-1(見つからない)と出る前の値が最後の閉じ括弧
こんな感じですか?



七次元

リンク

2006/10/10(Tue) 13:41:19|NO.2918

>あとは、repeat+instrで
>-1が返ってくるようになってからの前回ヒットした位置とか、
>ヒットした位置を全部配列にいれてしまうって手もあるね
もう出てたorz



うひょ

リンク

2006/10/10(Tue) 22:06:53|NO.2927

解決することができました。
主に考え方は2種類なようですね。
後ろから順番に見ていくやり方と、
instrで-1になるまで取得し、最後の値を確かめる方法、
どちらもとても参考になりました。
ありがとうございます。



ゆちボン

リンク

2006/10/13(Fri) 21:47:50|NO.2961

えーもう解決していますが、こんな方法もあるかと。
	;逆から検索
A="あいうえおかきくけこ" B=instr(A,0,"か") B=strlen(A)-B mes str(B) stop
単に普通に調べて全体文字数から引いてやるだけです。



七次元

リンク

2006/10/14(Sat) 17:22:50|NO.2975

一番外側(右側)だからその方法じゃ一番左側の位置になりますよ



男性A

リンク

2006/10/14(Sat) 18:11:20|NO.2978

というよりもこの場合、逆からの位置は分かりますが、ここでの質問とは多少方向が違うのではないでしょうか?



osakana

リンク

2006/10/18(Wed) 01:17:36|NO.3006

実用的では無い荒業ですが instr が使えます・・・。

txt="5*(4+3*(2-3))-1" txt2="" len=strlen(txt)-1 repeat len+1 poke txt2,cnt,peek(txt,len-cnt) loop i=len-instr(txt2,0,")") mes txt mes "最後の ')' は左から "+i+" / "+len+" 番目"
いや・・忘れてください。。。。



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