Hatena::Groupnadesiko

雪乃☆雫のなでしこ日和

2019-03-17

「文字検索」と「漢字か判定」

| 09:50

 マイナビ連載42目は、「再帰処理」についてでした。

https://news.mynavi.jp/article/nadeshiko-42/

 いや~、ワタシは別に、再帰処理につまずいた気はしないですけどね~。

 だって、それ以前に関数がわかんなかったし(爆)

 なでしこのお陰で急に賢くなって以降は、深く考えずに、ふつーに、それっぽいことをしていたように思う。



 それはさておき、「文字検索」です。

 そうは書いてないけど、v1非互換でした。

 なでしこ1の文字検索は、「文字列SでA文字目からBを検索する」とゆう命令でした。

 したがって、先頭の1文字目から検索を始めて、見つかったら「それ+1」文字目から次を検索・・・とゆう手順で、文書内にある全てのBを検索出来ました。(再帰って、こうゆうコトだよね(?))

#なでしこ1
C=1。新聞紙。
●新聞紙
 「しんぶんし」でCから「ん」を文字検索。  //「文字検索」
 もしそれが0ならば、 //ヒットしなかった場合は、
   戻る。       //関数から戻ることを忘れず!
 違えば、
   それ表示。
   C=それ+1。
   新聞紙。      //再帰

 まあ、なんかこんなような。

 ところが!

 なでしこ3の文字検索は、「文字列Sで文字列Aが何文字目あるか調べて返す」とゆうことになっており、検索開始位置の指定が出来ないんですよー。

 これでは、「何文字目」命令と、同じことっぽい。

 しくしくしくしく。どーすりゃいいんだorz


 ・・・・・・とりあえず、こんな感じか?

#なでしこ3
C=1。新聞紙。
●新聞紙
 「しんぶんし」でCから「ん」を文字検索改。
 もしそれが0ならば、
   戻る。
 違えば、
   文字位置=それ
   文字位置を表示。 //「それ表示」だと、v3の場合の後の「それ」が「undefined」になっちゃう
   C=文字位置+1。
   新聞紙。
 ここまで。
ここまで。

#-----------------------------------------------
#文字列SでA文字目からBを検索する
#なでしこ1の「文字検索」互換っぽいの
●文字検索改(SでAからBを)
 検索対象=(Sの文字数)-A+1。 //Aの位置も検索対象に含める
 仮=SのAから検索対象を文字抜出。
 数=(仮でBを文字検索)
 もし、数=0ならば、数で戻る。
 違えば、数+A-1で戻る
ここまで。
#-----------------------------------------------

 タブン、合ってると思うんだけど・・・



 さてさて、次にやりたいことは、指定した文字が漢字かどうかを調べることなんだけど、「文字種類」の中に、漢字か判定は無いので(1にも無い)自前でなんとかしないない

 ユニコードのCJK統合漢字の中に、ふつーに使うほとんどの漢字が含まれているのですが、ウィキペディアさまによると、Unicode 11.0では次のようになってるそうです。

U+4E00~U+9FEA   CJK Unified Ideographs(CJK統合漢字)
U+F900~U+FAFF   CJK Compatibility Ideographs(CJK互換漢字)
U+3400~U+4DFF   CJK Unified Ideographs Extension A(CJK統合漢字拡張A)
U+20000~U+2A6FF  CJK Unified Ideographs Extension B(CJK統合漢字拡張B)
U+2A700~U+2B734  CJK Unified Ideographs Extension C(CJK統合漢字拡張C)
U+2B740~U+2B81F  CJK Unified Ideographs Extension D(CJK統合漢字拡張D)
U+2B820~U+2CEAF  CJK Unified Ideographs Extension E(CJK統合漢字拡張E)
U+2CEB0~U+2EBE0  CJK Unified Ideographs Extension F(CJK統合漢字拡張F)

https://ja.wikipedia.org/wiki/CJK%E7%B5%B1%E5%90%88%E6%BC%A2%E5%AD%97


 とゆうわけで、正規表現で、

「^[\u4E00-\u9FEA\uF900-\uFAFF\u3400-\u4DFF\u20000-\u2EBE0]」で正規表現マッチ

で行けるかと思ったら、行かなかった。

 5桁のユニコードは、なんでもサロゲートペアなるものの対応が必要ラシイ。

https://ja.wikipedia.org/wiki/Unicode#.E3.82.B5.E3.83.AD.E3.82.B2.E3.83.BC.E3.83.88.E3.83.9A.E3.82.A2

 よくわかんないケド、このとうりに計算してエンコードすればいいのだろう。

 あと、ここによると第2面のU+20000~U+2FFFFは漢字専用領域となっているようなので、少なくともこまでは将来的に拡張される可能性があると考えられるので、

[\uD840-\uD87F][\uDC00-\uDFFF]

 こんな感じ?

 CJK統合漢字も、ATOKさまの文字パレットを見るとU+9FFFまで範囲になっているから、キリよくこまで含めとく?

 あと、繰り返しの「々」と漢数字の「〇」も含めておきたい。

U+3005  々(CJKの記号及び句読点:繰返し記号)
U+3007  〇(CJKの記号及び句読点:漢数字ゼロ)

 「〇」は、丸「○」とは別ですよ~。毛筆書体などを適用すると、違いが顕著なのでご注意です。

 でっ、こうなった。

#-----------------------------------------------
#文字列Sの1文字目が漢字か判定
●漢字か判定(Sが|Sの|Sを)
  Sを「^[\u3005\u3007\u4E00-\u9FFF\uF900-\uFAFF\u3400-\u4DFF]|[\uD840-\uD87F][\uDC00-\uDFFF]」で正規表現マッチ。
  もしそれがnullならばいいえ戻る。
  違えばはい戻るここまで。
#-----------------------------------------------
#以下はテスト
「○」が漢字か判定して表示。   //0 丸
「〇」が漢字か判定して表示。   //1 漢数字のゼロ
「一」が漢字か判定して表示。   //1 CJK統合漢字
「1」が漢字か判定して表示。   //0
「豈」が漢字か判定して表示。   //1 CJK互換漢字
「㐀」が漢字か判定して表示。   //1 CJK統合漢字拡張A
「𠀀」が漢字か判定して表示。   //1 CJK統合漢字拡張B

 しかし、頑張って対応させたものの、果たして拡張部分は必要だったのか;

 見たこともないヤツばっかだ;;;

 して、扱おうとしてるテキストは青文庫のなので、文字コードはJIS X 0208 の範囲に限定されていて、それ以外のは註になってるんだよね。

 ウィキペディアさまによると、「IS X 0208のすべての漢字が、UCS/Unicodeの基本多言語面のいずれかの符号位置に対応する」・・・とゆうことらしいから、明らかにいらなかった気が(´・ω・`)

https://ja.wikipedia.org/wiki/JIS_X_0208#ISO/IEC_10646%E3%81%8A%E3%82%88%E3%81%B3Unicode

 まあ、他のことでも使うかもしないし、足りないよりかは網羅している方がいいとゆうことにしようそうしよう。



 んなこんなでやろうとしていたことは、折角なでしこさんがしゃべるようになったので、青文庫でも読み上げさせてみっかなとゆうことで、読み上げにルビを反映させることでした。

 何しろ、のまま読ますと「兎《と》に角《かく》」を「うさぎきごうときごうにかくきごうかくきごう」と読んじゃうんですからねヽ(;´Д`)ノ

 まず「《」を検索して、漢字か判定でルビの付いてる範囲を調べ、それとルビの記号「《》」を消せば(置換)ルビ部分だけが残るって寸法です。

 しかし・・・もはるかさんの読み上げ精度がひどい(「沢山」を「さわやま」と読んじゃうとか!(´д`;)上に、最近Fire7を手に入れたところ、標準でみずきさんがKindleを読み上げてくれるんで、もうなんだかな~;

 まあ、みずきさんもんなに上手に読んでくれるわけじゃないですけどねw

ゲスト



トラックバック - http://nadesiko.g.hatena.ne.jp/snowdrops89/20190317