DelFusa Blog 総本山

プログラミングの話題とかです。

NEW | PAGE-SELECT | NEXT

≫ EDIT

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

| スポンサー広告 | --:-- | comments(-) | trackbacks(-) | TOP↑

≫ EDIT

文字列検索処理


   ∧,,∧
   ミ,,゚Д゚彡
   ミ⊃ ミ
  ~ミ  ,,0
   し'´


Delphi-fan ☆文字列を後方から検索する。
http://hiderin.air-nifty.com/delphi/2008/02/index.html#entry-50159996


こちらをみると、AnsiReverseString関数
なるものが存在するのですね。


それにしても部分文字列検索などがDelphiは貧弱なので私は
大幅にこのあたりのプログラムを自作ライブラリとして揃えています。

StringUnit
http://delfusa.main.jp/delfusafloor/opensource/delfusalibrary/20070828160200/StringUnit/StringUnitLight.pas.txt



履歴を見ると、何年越しの実装なのかと....
おばあちゃんのつくる漬け物みたいな年齢になってきましたね。

Unitのソース量は膨大ですが結局interfaceだけ見ればいいわけで

function WidePosForward(const SubStr, S: WideString; IgnoreCase: Boolean = False): Integer;
function WidePosBackward(const SubStr, S: WideString; IgnoreCase: Boolean = False): Integer;
function AnsiPosForward(const SubStr, S: string; IgnoreCase: Boolean = False): Integer;
function AnsiPosBackward(const SubStr, S: string; IgnoreCase: Boolean = False): Integer;

function RangeAnsiPosForward(const SubStr, S: String; Index: Integer = 1; Count: Integer = MaxInt; IgnoreCase: Boolean = False): Integer;
function RangeAnsiPosBackward(const SubStr, S: String; Index: Integer = 1; Count: Integer = MaxInt; IgnoreCase: Boolean = False): Integer;
function RangeWidePosForward(const SubStr, S: WideString; Index: Integer = 1; Count: Integer = MaxInt; IgnoreCase: Boolean = False): Integer;
function RangeWidePosBackward(const SubStr, S: WideString; Index: Integer = 1; Count: Integer = MaxInt; IgnoreCase: Boolean = False): Integer;

こんなもんかな。

結局は何段階か、ラッピングしているだけなわけですが

順方向、逆方向、範囲指定、大小文字指定
これくらいできれば問題ないでしょう。

どーぞです。
スポンサーサイト

| 未分類 | 23:08 | comments:11 | trackbacks(-) | TOP↑

COMMENT

ちなみに、unicodeには対応してません。。。。つまり、widestring=UTF2Stringには対応ですけど、例の議論からは、蚊帳の外でございますよ。

| ミ・Д・彡 | 2008/03/26 03:32 | URL | ≫ EDIT

え?
サロゲート領域は通常の文字コード領域とは重なっていないから、合字の問題を除けばよほど不作法なコードを組んでいない限り動かないはずはない。のですが。

合字の問題まで広げると、いわゆる大文字小文字区別なしとか全角/半角曖昧一致などと同質の問題ですので、それをサポートしていないからと言って特に気にすることはないと思いますよ。それこそ仕様の問題。です。
Normalization の API は OS に付属していますから、正規化文字列にしてから検索すればよろしい。

食べたことない物には興味が出ない性格なのかもしれないけど、一度勇気を出して .NET Framework での文字/文字列実装の技術を学んでみると良いと思います。腐っても Microsoft, 過去の反省を踏まえてよくまとまっていますよ。

| NAME | 2008/03/26 20:53 | URL | ≫ EDIT

おおおお!
ご意見ありがとうございます。

サロゲ領域についてですが、部分範囲でそれを考慮していなくて、
バイト数固定での思想しかない実装ですから
やっぱり普通に対応は出来ていないとは思いますが、
だからといって、大半のunicode文字には対応できるので
問題ないっちゃ、問題ないんですけどね。

テストファーストコードがあるのですぐにUnicodeStringに対応できるはず。
早くFTに参加してみたいです。

Normalization の事や.NETの文字列処理のヒント助かります。
誰かがまとめた見やすいページなどご存じでしたら
教えてください。

MSも中ではいろんな人ががんばって実装しているんでしょうね。
CodeGearも標準で文字列処理が充実してたらいいなと
昔は不満に思いましたが、

受け身の姿勢より攻めの姿勢の方がよかろうということで
無ければ作ってしまえと、ずんずん作り続けた結果
こういう事になってます。

自分の自作のものは、CodeGearが標準化しても遜色ないレベルの
高品質実装をしたいと思っています。
※内部実装の高速化はともかく、関数やメソッドやクラス構成のインターフェース部分は
.NETの文字列処理思想を理解して反映すると言うことは
すぐに出来ると思ってます。

ご利用ください。
そして誰でも改良してよいものにして頂ければと思いますよー。

| ミ・д・彡 | 2008/03/27 09:49 | URL | ≫ EDIT

FT は、あなたのライブラリを磨くために用意されているわけでは無いと思いますが。

>誰かがまとめた見やすいページ
ちょっとは MSDN とか見てくださいよ。努力している振りだけでも見せてくれればねぇ

>攻めの姿勢
FastMM の元になった FastCode の方々の歴史/業績をよく理解して、その上で彼らの一員となる。くらいの野望を期待しますよ。

たぶん、無理だと思いますが。

.NET の「文字列」はサロゲート処理をしない UTF16 なんですってば。
しかもライブラリ全体では UTF-全部 with サロゲート処理、さらには EUC/MIME まで処理できるようになっています。
文字の格納形式そのものとインターフェースでどのようにエンコードするのかを明確に切り分けるところから設計し直したライブラリ。ってのを一回見てから、話を始めた方が良いと思います。

たぶん、人の言うことは聞いてくれないよねぇ。あんたの性格からすると。

| ほんと何度目かなぁ。こんな事書くの | 2008/03/27 18:25 | URL | ≫ EDIT

サロゲ領域についてですが、部分範囲でそれを考慮していなくて、バイト数固定での思想しかない実装

だったとしても(ShiftJIS での漢字第二バイトと第一バイトとの衝突のような)矛盾がでないように「設計」されているのですよ。

通勤の合間とかに、ちょっとだけでも理由を考えてみてくださいな。

| ではまた | 2008/03/27 18:31 | URL | ≫ EDIT

>NET の「文字列」はサロゲート処理をしない UTF16 なんですってば。
そうでしたっけ?単にほにゃらら.Lengthがサロゲートペア(及び結合文字列)の場合にワードカウントを返す仕様なだけでは?

"サロゲート処理をしない UTF16"ってUCS-2ですよ?UCS-2にだってサロゲート領域はある(この領域に文字は割り当てられない)のですから。

| DEKO | 2008/03/28 01:52 | URL | ≫ EDIT

>サロゲ領域についてですが、部分範囲でそれを考慮していなくて、バイト数固定での思想しかない実装だったとしても(ShiftJIS での漢字第二バイトと第一バイトとの衝突のような)矛盾がでないように「設計」されているのですよ。

...ならばWord単位のMidStrをワード固定で実装するとして、
a := MidStr(Str, 3, 3);
ここでStrにサロゲートペアが含まれても、正しく動作すると、お考えなのか?サロゲートペアの第二ワードから選択されてしまった場合でも問題は発生しないと?

| DEKO | 2008/03/28 02:08 | URL | ≫ EDIT

ワード固定の実装だと
1.サロゲートペアの1ワード目まで切り出した文字列。
2.サロゲートペアの2ワード目から切り出した文字列。

...さて、1+2で変な文字が生成されやしませんか?

| DEKO | 2008/03/28 02:11 | URL | ≫ EDIT

僕も30秒ぐらいでわかりましたが、、、、30秒も、迷った自分が情けない....

理屈じゃないんですよ。。。コード書けない人の脳内は。まちがっちゃった事で見下したかったりするんでしょう....

DEKOさん、すいません。ほんと、いつもありがとうございます。

もう少し時間がとれたら、サロゲペア対応コードも、しっかり作り込んでいきたいと思います。
まあ。ティブロン後ですね。

たぶん、ティブロンでもVCLではそういう文字検索対応関数はでてこない気がするので、(でてきたら万々歳ですが...)
自前実装する気構えは必要かなと、思ってます。

| ミ・Д・彡 | 2008/03/28 03:09 | URL | ≫ EDIT

>文字検索対応関数
Unicodeに限って言えば結構簡単。
UTF-8に変換してから処理すればいいよ。
この利点はMatz氏も言っていたね。

ただ、現行DelphiのUTF8EncodeではWideStringにUTF-16を突っ込んだらサロゲートペアが正しく処理されないし、そもそもUTF8String操作用の関数が決定的に不足している。

...それを補うのが(ゲフンゲフン)だったりする。

# そのうち解る>ゲフンゲフン

| DEKO | 2008/03/28 03:23 | URL | ≫ EDIT

Nick HodgesさんのBlogによれば
Unicode用のサポート関数を
相当追加したみたいですよ。

追伸:誤字の指摘ありがとうございました。

| Oldtpfun | 2008/03/28 09:05 | URL | ≫ EDIT















非公開コメント

PREV | PAGE-SELECT | NEXT

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。