Slide 1

Slide 1 text

POSIX文字クラスでの躓き 2023/08/26 (Sat) Kanazawa.rb meetup#132 muryoimpl

Slide 2

Slide 2 text

ある日の irb にて ● 環境は、 ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x86_64-linux] ● 以下のコードを入力してみたが、イメージしていたものと違う動作をした。 irb(main):001:0:> /[[:alnum:]]+/.match?(“10”) : true irb(main):002:0:> /[[:alnum:]]+/.match?(“あ0”) : true [[:alnum:]] で “あ” で true ? なぜ?から調査は始まった。

Slide 3

Slide 3 text

ChatGPT さんに訊いてみたが…… どうやら、私がおかしなことを 言ってる感じですね

Slide 4

Slide 4 text

まず「Ruby 正規表現」でググる

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

正規表現のページを確認すると ● [:alnum:] は POSIX 文字クラスまたはPOSIXブラケット というもの。 また、[:^クラス名:]という記法でその否定を意味する。 (以下、POSIXブラケットと呼ぶ) ● 似たような機能を持つ記法に Unicode プロパティというものもある。 ○ \p{property-name} ○ \p{^property-name} (否定) ○ 具体例: \p{Letter}

Slide 7

Slide 7 text

エンコーディングによって挙動が変わるらしい。 詳しくは Onigmo のドキュメントを見ろとある。

Slide 8

Slide 8 text

Onigmo のドキュメント(日本語版)を 見る https://github.com/k-takata/Onigmo/blob/master/doc/RE.ja

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

Unicodeプロパティ ● Rubyのデフォルトエンコーディングは UTF-8 irb(main):001:0:> "あ".encoding : # ● alnum は Unicodeプロパティの Letter | Mark | Decimal_Number に相当する。こ れは Ruby の正規表現のページにも同じ記載があった。 ● Mark と Decimal_Number はぼんやりとイメージが湧くが、Letter の範囲は? ○ https://util.unicode.org/UnicodeJsps/list-unicodeset.jsp にて、Unocodeプロパティを入力して範 囲を確認してみる

Slide 12

Slide 12 text

ブラウザでアクセスして確認する

Slide 13

Slide 13 text

Unicodeプロパティ \p{Letter} ● ひらがな、漢字等かなりの広範囲の”文字”が含まれていた。 ● Onigmo のドキュメントにあったとおり、エンコーディングが Unicode の場合におい て、 実はほとんどすべての文字をカバーしてしまう ● つまり、alnum は alphabet と number ではない。 Letter が alphabet のみなら ず、広範囲の文字をカバーしてしまうため ● 英数字のみならば、/ [a-zA-Z0-9]+/.match?(“あ”) みたいに、明示的に範囲を指定 するか ● 正規表現のページのオプションによると、/(?a:[[:alnum:]]+)/.match?("あ") のよう に、オプションで動作が変えられるようだ

Slide 14

Slide 14 text

d, u は、UnicodeではPOSIXブラケットは非ASCII文字にマッチしてしまう。 a は、POSIXブラケットは非ASCII文字にマッチしないので、:alnum: は英数字にマッチする

Slide 15

Slide 15 text

まとめ ● Rubyのデフォルトエンコーディングは UTF-8 、正規表現でPOSIXブラケットを見た ままのイメージで使うと痛い目に遭う ● Onigmo の POSIXブラケットはエンコーディングによって挙動が変わるため、使う場 合は文字列のエンコーディングを意識する必要がある ● 正規表現のみならず、処理を実装するときは失敗パターンも確認しましょう ● ChatGPT さんの意見を鵜呑みにしてはいけない