0

私は、単一の正規表現行で可能な比較的単純な語順のセットを一致させることに本当に苦労しています。

基本的に、私はこれらの(他の文法的に類似した)可能性と一致させたいと思います:

「変数をオンに設定」

「変数をオフに設定」

「変数をオンに設定」

「変数をオフに設定」

「変数を設定する」

「変数に設定」

「変数に設定」

「varを設定する」

必要なグループは、「var」(任意の1つの単語で可能)と、常にオンまたはオフになる値だけです。それが基本的な考え方です。

それを念頭に置いて、2つの可能な文法構造があります。

(on/off) (perhaps a word) (a word)

(a word) (on/off)

私はこれらの可能性を次の正規表現と独立して一致させることができました。

/((on |off )([a-z]{1,})? ([a-z]{2,}))/i


/([a-z]{2,}) (on|off)/i

だから、私はこれができると思いました:

/(((on |off )([a-z]{1,})? ([a-z]{2,})))|(([a-z]{2,}) (on|off))/i

これは(フレーズ1)|(フレーズ2)ですが、フレーズ2は、「set」が名前であると考えて、「setoff」と常に一致します。私も試しました:

/((?!set)) (((on |off )([a-z]{1,})? ([a-z]{2,})))|(([a-z]{2,}) (on|off))/i

成功しませんでした。


編集1:また、私はこれらのフレーズがファイルのどこにでもあることに言及することを怠りました。それらは独立した線上にありません。

例:「これは変数を設定する方法です」は「変数を設定する」と同じくらい可能性があります


質問:

  1. 別々に一致させることなくこれを一緒に行うことができる最良の方法は何ですか?

  2. 正規表現ORステートメントの一致する順序を強制する方法はありますか?

4

2 に答える 2

2

'the'は常に'var'の前に表示される場合があります:

((the)? var)

'set'は常に式を開始します:

^set

'on'と'off'は相互に排他的ですが、1つが必要です。

(on|off)

「var」と「on」/「off」は順不同で次々に表示されます。すべて一緒に今:

^set ((the)? var (on|off)|(on|off) (the)? var)$

注:私は.NET開発者です。正規表現はかなり標準的であり、上記は機能するはずですが、perlでこれを書くためのより効率的な方法があるかもしれません。

于 2013-01-15T00:12:40.190 に答える
0

複雑なデータを照合しようとするときはいつでも、おそらく文法を作成しようとする必要があります。Perl正規表現を使用すると、を介して再帰的文法を指定できます(?(DEFINE)...)

use strict; use warnings; use feature 'say';
my $grammar = qr(
    set \s+ (?:the \s+)? (?<variable>(?&VAR)) \s+ (?:to \s+)? (?<value>(?&VAL))
  | set \s+ (?<value>(?&VAL)) \s+ (?:the \s+)? (?<variable>(?&VAR))

  (?(DEFINE)
    (?<VAL> on | off) # edit only here to add new values
    (?<VAR> (?!the|(?&VAL)) \w+)
  )
)x; # /x -- whitespace is irrelevant

while(<>){
  if (/$grammar/) { say "> val: $+{value} var: $+{variable}" }
  else            { say "> no match" }
}

注意する構文:(?&rule)名前付きルールを呼び出します。名前付きキャプチャ、ハッシュ(?<name>pattern)経由のアクセスを許可します。ブロック%+内のルールを宣言するためにも使用されます。(DEFINE)

セッション例:

set the switch to off!
> val: off var: switch
I would like to set something on fire...
> val: on var: something
set on the set!
> val: on var: set
set on the set off something
> val: on var: set
set on off
> no match

変数も値と一致しないと主張することで、文法をかなり明確にしたことに注意してください。ただし、上記の例は、予想どおりに解析されなかった可能性のあるいくつかの興味深いケースを示しています。

正規表現内に文法を書くためのより強力な方法については、Regexp::Grammarsを参照してください。

于 2013-01-15T00:53:14.807 に答える