2

gedit でファイルの一部を強調表示するために、GtkSourceView 言語ファイルを作成しようとしています。私が直面している問題は、少なくとも最初の 4 文字を含み、スペルが正しい単語を強調表示したいということです。説明のために、次の 4 つのパターンがあるとします。

variable
vari
variab
variabel

そして、最初の 3 つを特定したいのですが、4 つ目は特定したくありません。最初の 3 つがすべて、対象の「変数」の正しいスペルの部分文字列だからです。仕事を成し遂げるのは何を使うかです

\bvari(a|ab|abl|able)?\b

しかし、これは長い単語では非常に退屈になる可能性があります。したがって、完全な言語ファイルでは、次のようになります。

<?xml version="1.0" encoding="UTF-8"?>
  <language id="foo" _name="foo" version="2.0" _section="Other">
  <metadata>
     <property name="mimetypes">text/x-foo</property>
     <property name="globs">*.foo</property>
  </metadata>

  <styles>
    <style id="keyword" _name="Keyword" map-to="def:keyword"/>
  </styles>

  <default-regex-options case-sensitive="false"/>

  <definitions>
    <context id="foo">
      <include>
        <context id="keyword" style-ref="keyword">
          <keyword>\bvari(a|ab|abl|able)\b</keyword>
        </context>
      </include>
    </context>
  </definitions>
</language>

これに対する解決策を見つけることができませんでした-正規表現に非常に慣れておらず、この質問の正しい言い回しがわからないためです。この問題に対する簡単で効率的な解決策はありますか?

4

1 に答える 1

3

残念ながら、これほど面倒な方法はありません。

パターンについて:GtkSourceView NFA 正規表現エンジンである PCRE 正規表現エンジンを使用することに注意してください。したがって、代替を記述すると、一致する最初の代替(左から右)abcdefが成功し、正規表現エンジンは、パターン(a|ab|abc|abcde|abcdef)が返す文字列の例のように、より右側にある他の代替をテストしませんa (DFA が一致する最長の代替なので、abcdef)

これは、最後に単語境界があるためにのみパターンが機能することを意味します(単語全体に対してvariable、各選択肢は成功しますが、単語境界に達すると、正規表現エンジンはバックトラックして次の選択肢をテストする必要があり、最後の選択肢まで続きます) .)

結論として、エンジンへの不要な作業を避けるために、最長の代替案から最短の代替案への代替を記述することをお勧めします。

\bvari(able|abl|ab|a)?\b

別の可能性は、次のようにパターンを設計することです。

\bvari(a(b(le?)?)?)?\b

この場合、正規表現エンジンは、適切な代替を見つける必要なく、パターンの最後までまっすぐ進みます。ただし、文字を何度も書く必要がないため、書くのは簡単ではありませんが、少し短くなることに注意してください。

于 2015-01-28T16:24:56.537 に答える