2016-05-09 14 views
4

::文法、次のトークンを考慮してください。大文字と小文字を区別しない正規表現でハッシュキー:: Perlモジュールの正規表現で文法

<token: command>  <%commands> 

このトークンは、異なるさまざまなを解析、複雑な文法の一部であり、文章。 「Basic_import」のようなマッチングキーワードの

our %commands = (
    'Basic_import' => 1, 
    'Wait'   => 1, 
    'Reload'  => 1, 
    'Log'   => 1, 
); 

これは動作しますが、「待っ:

このトークンは、私が(任意の関数の外に、当然のことながら)以下のように定義されているハッシュ%コマンド、のいずれかの単語に一致します"basic_import"、 "wait"などの単語で一致させたい場合もあります。

このキーワードを複数回コピーして貼り付けなくても、このハッシュケースを非表示にするにはどうすればよいですか?これは複雑な文法の一部なので、Regexp :: Grammarsを使いたいので、この例外のためにgrepに戻す必要はありません。 <%commands>WaitingWaitにマッチするようにドキュメントから

+1

そのようなものではありません。これはRegexp :: Grammarsの質問 – ikegami

+0

残念ながら、ハッシュを結ぶことは役に立たないようです。 – psgels

+0

@psgels、 '(?i:<%commands>)'は動作しますか?そうでない場合は、自分でパターンを作成する必要があります。 – ikegami

答えて

1

あなたは、ハッシュ検索の大文字小文字を区別しません作るためにHash::Case::Preserveを使用することができます。

use strict; 
use warnings 'all'; 

use Data::Dump; 
use Hash::Case::Preserve; 
use Regexp::Grammars; 

tie my %commands, 'Hash::Case::Preserve'; 

%commands = (
    'Basic_import' => 1, 
    'Wait'   => 1, 
    'Reload'  => 1, 
    'Log'   => 1, 
); 

my $grammar = qr{ 

    <command> 

    <token: command> <%commands> 

}; 

dd \%/ if 'basic_import' =~ $grammar; 

出力:あなたはがそれに任意の値を挿入する前tieハッシュに持って

{ "" => "basic_import", "command" => "basic_import" } 

注意。

+0

はい、これは動作します。私は初めて試したときに何かミスタイプをしているに違いありません。ありがとう! – psgels

+1

ヒント: ' \ b <%commands> \ b'は、printfoo(); vs' print foo(); 'の問題に対処するので、より良いでしょう。 ( '%commands'のキーが' \ w'char以外のもので始まるか終わるかを調整する必要があります)。 – ikegami

4

は、それが聞こえるので、<%commands>のも、大文字と小文字を区別しないバージョンが理想的とは言えないだろう。

通常、汎用識別子を照合して、その識別子が有効なコマンドであるかどうかを個別にチェックします。これは、printfoo();がPerlのprint foo();と等価でないことを防ぎます。

私は次のことを提案してもよい:

use feature qw(fc); 

our %commands = map { fc($_) => 1 } qw(
    Basic_import 
    Wait 
    Reload 
    Log 
); 

<rule: command> (<ident>) <require: (?{ $commands{fc($CAPTURE)} })> 

<token: ident> \w+ 

あなたが5.16よりも古いバージョンのPerlとの後方互換性が必要な場合は、おそらく代わりにfclcを使用して逃げることができます。

+0

の代わりに使用する"ドキュメントのように... "私はRegexp :: Grammarsを使ったことは一度もありませんが、トークンが何であるかという奇妙な考えがあるようです。また、アンカーをパターンに追加することで回避することもできます: '$ $ grammar = qr {\ A \ z <%commands>}; ' – ThisSuitIsBlackNot

+1

@ThisSuitIsBlackNot、どこにでも境界を強制する必要はありません「」が使用されます。チェックはトークンの内側になければなりません。代わりに ' \ b <%commands> \ b'を使用してください(ただし、'%commands'のすべてのキーは '\ w'文字で始まり、終わります)。 – ikegami

関連する問題