戻り読み不具合、他

  1. 「ベータの名は外させない! ──絶対にだ!」
    を標榜とするkuroさんが戦う謎の勢力の一員とみなされそうですが、
    鬼雲が対応するまでまだしばらくお預けになりそうな話と、軽い不具合です。
    (Win7, Mery (x86) Version 2.6.5β)

    ☑ 戻り読みの正規表現で"define"や"definition"が使えない
    戻り読みの正規表現で、不具合と思しき動作に遭遇したので報告です。
    さく○さんの方でも駄目なので鬼雲の問題でしょうが、
    kuroさんから報告してもらった方が話が通り易そうなのでお任せします。
    サンプルテキストと正規表現で、いろいろイジって確認してみてください。

    サンプルテキスト
    ```text
    high-definition television
    HDTV,高精細度テレビジョン
    high-ignition television
    HITV,高発火テレビジョン
    ```

    正規表現サンプル
    ```reg
    // × 指定できない文字列がある事に気づいたのが発端
    (?<=definition) television
    // ○ 少し削って、これだと動作する
    (?<=finition) television
    // × "e"を付けるだけで動かない
    (?<=efinition) television
    // ○ んじゃ逆から……、これは動作する
    (?<=ef)inition television
    // × ん? もう動かない
    (?<=efi)nition television
    // 結局この"efi"の文字列が含まれるものは全部駄目っぽい
    //   例:bluefish, battlefield, briefing, deficit, etc.
    //(排他用の変数名がそのまま入っちゃった感じなのかな?)
    ```

    ☑ マーカーが灯ったままになる
    手順
     - 自動マーカーをON
     - 文字列を選択してからキャレットのすぐ脇をクリック

    本来ならこの手順で選択状態が解除されているはずが、
    自動マーカーは灯ったままになる不具合があります。
    キャレットが移動しない選択解除なので、
    マーカー側のチェックが働いてないのかも?

    選択状態だと思って他所にコピペしたら、
    一行まるっと突っ込むミスが多発したので見つけました。
    (あ、多発したのは私の雑な操作が主原因だわwwwスマヌ ^o^)

    ☑ DirectWriteが効かなくなる
    縦書き表示にしてから元に戻すと、表示上DirectWriteがおっふの状態になるようです。
    これは誰かが報告してるか、既に把握してそうですが、一応。

    それでは、よろしくお願いします。

     |  玄米茶  |  返信
  2. 玄米茶さん、こんにちは。
    失礼ながら割り込ませていただきます。
    この正規表現については少し知っていますので、ご説明します。

    まず大切なことが抜けています(^^)

    これが起こるのは、
    ☐大文字と小文字を区別する(C)

    としたとき、または正規表現中に (?i) を使うときだけです。

    もし
    ☑大文字と小文字を区別する(C)

    としていれば正しく検索できます。

    これは、以前から何回か取り上げられていますが、直近では、
    Ruby で発生する問題として 2017-07-14 に鬼雲の GitHub 
    に"ss" を含む文字列について報告され、その後 "st" でも同様
    の指摘が続いていますが応答はなく未対応です。

    というのも、これがバグかというと、あいまいな仕様を忠実に実装
    していることによるものなので、正規表現エンジンの側からすると、
    当たり前の制限事項だとも言えます。

    検索ができない理由は、
    正規表現の文法エラー (VARLEN Syntax-Error) です。

    この戻り読み (look-behind) では、文字数の可変は認められて
    いません。
    唯一の例外はトップレベルでの OR (|) での併記のみです。

    ここで可変は使っていないのに、と思われる方がほとんどだと思い
    ますが、大文字と小文字を区別しないとき、Unicode の CaseFolding 
    に従った代替判定が行われます。この CaseFolding に、複数文字を
    1文字に置き換えるものが含まれているため、この判定の過程で
    「可変長」とみなされて、文法エラーになります。

    句読点を含むとかなりの数が対象になりますが、英語アルファベット
    のみの組み合わせでは

      ss    U+1E9E ẞ
      st    U+FB00 ff
      ff    U+FB01 fi
      fi    U+FB02 fl
      fl    U+FB03 ffi
      ffi   U+FB04 ffl
      ffl   U+FB05 ſt

    の 7 つです。
    最初の ss はドイツ語で使われる文字エスツェット ẞ U+1E9E で、
    残りは多くの言語に使われるリガチャ(合字 LIGATURE)に、
    割り当てられたコードポイントです。

    Unicode の正規表現にとって、大文字と小文字を区別しないこと
    (Ignore-case) は重荷です。内部でとても多くの判定を行います。

    どうしても、大文字・小文字の同一判定をするのであれば、

    (?<=definition) television

    (?<=(?-i)definition) television

    (?<=de(?-i:fi|FI|fI|Fi)nition) television

    のように、戻り読み全体の Ignore_Case を解除するか、必要ならば、
    該当の文字だけを解除して、自分で大文字小文字判定を展開するよう
    にします。

    仕様変更を伴う改造をした正規表現エンジンでは対応できますが、
    Kuro さんはあまりそのような対応をお好みではないと思うので、
    鬼雲 (Ruby) 公式版の制限事項として、解決されるまで、理解した
    うえで回避する方法を工夫することになります。

    また、文法エラーにはなりませんが、
    文字集合([] 文字クラス Character Class)の中でこれらの文字列を
    使った場合にも、同じ代替判定が行われます。
    ただし、文字集合の否定([^ ])については、(負荷が高く)あいまい
    さが増すという理由で代替判定をしない仕様(Perl 準拠)になって
    います。

     |  inuuik  |  返信
  3. 【訂正】ずれてました…

      ss    U+1E9E ẞ
      ff    U+FB00 ff
      fi    U+FB01 fi
      fl    U+FB02 fl
      ffi   U+FB03 ffi
      ffl   U+FB04 ffl
      st    U+FB05 ſt

    の 7 つです。

     |  inuuik  |  返信
  4. 「勝手に合字判定やめてー!」

    inuuikさん、わかりやすい解説ありがとうございます。(FAQに推薦です)
    内部ではそんなことになっていたのですね。
    えっ!? 前はこれでよかったよね!?
    って鬼雲ver5あたり引っ張り出して確認しちゃったw

    (?<=de.inition) television
    簡易ならこれでもよさそうですが、合字のパターンが多いので、
    憶えておいて見つけたら修正とかあまり現実的じゃないですね。
    んー対策で単純に大小文字区別のオプション付けると、
    今度は取りこぼしが怖いかも^^;

    もうマシンパワー使っていいから、そこら辺上手いことやってよ?
    って言うと、AIの反乱が起きた時に真っ先に粛清対象の発言になりそうなので、
    素直に書き直すことにします。リソース大事!

    ということで、口実もなくなったことだし、
    kuroさんそろそろベータの文字が無いものを期待してますよ。(とばっちり)

     |  玄米茶  |  返信
  5. ちょっと意味が変わるけど、戻り読みの代わりに\Kを 使えないかな?
    definition\K television
    テキストを先頭から順に検索するだけなら問題なさそう。
    カーソル位置がdefinitionの中にあると検索されないけど。

     |  foo  |  返信
  6. 長っ!そして内容重っ!週末に読ませていただくのでしばしお待ちを。

    > kuroさんそろそろベータの文字が無いものを期待してますよ。(とばっちり)
    ベータ取ったらシェアウェアになりますよ?ニヤリ

     |  Kuro  |  返信
  7. はじめましてfooさん。
    そうですね、単純に\Kを使うのもいいですね。
    いろんな方法が可能なので、こう制限が多いと戻り読み自体を
    使わなくなってしまいそうです^^;

    > ベータ取ったらシェアウェアになりますよ?ニヤリ
    おまっ! 何を??

     |  玄米茶  |  返信
  8. 週末になったので約束通りご返信を。なるほど、把握。

    > ☑ 戻り読みの正規表現で"define"や"definition"が使えない
    こちらに関しましては inuuik さんのご回答の通りですね。

    その後、対策方法なども含めて inuuik さんからご連絡をいただきました。
    inuuik さん、ありがとうございました。(それとお大事に…)

    > 仕様変更を伴う改造をした正規表現エンジンでは対応できますが、
    > Kuro さんはあまりそのような対応をお好みではないと思うので、

    まさにその通りです ^^;
    inuuik さん、せっかく修正方法までご提示いただいたのにすみません。
    鬼雲のソースまでメンテしなきゃならなくなると私のメンタルが死んでしまいます。

    > ☑ マーカーが灯ったままになる
    ご指摘の通り、キャレットが移動しないのでマーカー側のチェックが動いていませんでした。
    次のバージョンでは修正してみます。

    > ☑ DirectWriteが効かなくなる
    Windows 7 ですと DirectWrite は縦書きに対応していませんので、縦書きにしたとたんに DirectWrite がオフになってしまい、横書きに戻してもそのまんまでしたね ^^;
    横書きに戻したときに復旧するように修正しておきます。

    (ちなみに Windows 7 で DirectWrite の縦書きができないのは私のせいじゃなくて、そもそも Windows 7 の DirectWrite に縦書き機能がないからです)

    > ベータ取ったらシェアウェアになりますよ?ニヤリ
    いやぁ、時代の流れ的にコードサイニング証明書を付けないと厳しい感じなので、なんとか費用 (年間 5 万円ぐらい) をひねり出したいのです ^^;
    コードサイニングがあれば Windows ストアアプリ化もできますし、将来性も見えてくるかなと。
    (3 つぐらいしか売れないっていうオチもありそうですが)

    ・フル機能使えるけど、時々「買ってね!テヘペロ!」なメッセージが表示されるタイプ (秀〇さん、Sublime Text さんなど)
    ・余計なメッセージは表示されないけど、機能制限があるタイプ (E〇Editor フリー版さんなど)
    ・フル機能使えてメッセージも表示されないけどシェアウェアなタイプ (性善説)
    ・誰かが毎年 5 万円振り込んでくれるタイプ (足長おじさん)

    などを考えておりますが、ホント、フリーソフトに厳しい世の中になりました。

     |  Kuro  |  返信
スポンサーリンク