-1

or別のセットを実行する必要がある式を一致させるにはどうすればよいですか?

つまり、フォーマットの何かをどのように一致させるのですか

[
  [
    [ a | b ] |
    [ x | y ]
  ]
]

ここで、a、b、x、および y は文字列です。

のようなフレーズを一致させたい

a
b
x
y
a x
a y
b x
b y
x a
x b
y a
y b

しかし、次のようなものではありません:

a b
x y
z z 

Boost Xpressiveで使用しようとしているので、ECMAScript または Perl タイプの正規表現を使用するオプションがあります。

4

4 に答える 4

4

次のように実行できます。

[ab] [xy]|[xy] [ab]|[abxy]

ここには 3 つの選択肢があります。

  • a、、、b(1文字x)のみy
  • または 2 文字、aまたは またはのb前に来て、間にスペースを入れます。xy
  • または 2 文字、xまたは またはのy前に来て、間にスペースを入れます。ab

[abxy]念のため、検索すると、単一のものを検索する前に、前のもの(ペアになっているもの)が検索されます。正規表現を使用して検索する場合は順序が重要ですが、検証を行う場合はそれほど重要ではありません。

それを書く別の方法:

[ab]( [xy])?|[xy]( [ab])?

これは文字に対してのみ機能しますが、文字列に対して機能させることができます。たとえば、4 つの文字列s1, s2, s3,があるとしs4ます。

(s1|s2)( (s3|s4))?|(s3|s4)( (s1|s2))?

以下を検索します。

  • or のいずれs1s2、かもしれないし、そうでないかもしれません (の 0 または 1 つのインスタンス) の後にs3orが続きますs4
  • (逆に)

s1これは、s2、 など (単一の文字列) 、s2 s3s3 s2など (ペアで、順序を逆にすることができます)のすべてのケースをカバーします。上記の正規表現は、量指定子のデフォルトの貪欲なプロパティにより、単一の文字列に頼る前に長いバージョン (ペアになっている) を検索します。

上記の正規表現でキャプチャ グループ を使用していることに注意してください。これにより、内部(pattern)に一致する文字列の位置が記録されます。パターンに一致するテキストを参照する必要がない場合は、pattern非キャプチャ グループにすることができます。(?:pattern)これにより、いくつかのクロック サイクルが節約されます。

(?:s1|s2)(?: (?:s3|s4))?|(?:s3|s4)(?: (?:s1|s2))?

(他の正規表現のキャプチャ グループをキャプチャ グループに変更するタスクは、演習として残します。追加するのと同じくらい簡単です)?:

検索または検証?

そのようなパターンを見つけたい場合は、上記の正規表現が機能するはずです。

文字列がパターンに一致することを検証する場合は、アンカー^(文字列の先頭に一致)、$(文字列の末尾に一致) を使用して、文字列が正確な形式に従っていることを確認する必要があります。

^([ab] [xy]|[xy] [ab]|[abxy])$
^([ab]( [xy])?|[xy]( [ab])?)$
^((s1|s2)( (s3|s4))?|(s3|s4)( (s1|s2))?)$
^(?:(?:s1|s2)(?: (?:s3|s4))?|(?:s3|s4)(?: (?:s1|s2))?)$

上記のセクションの正規表現を()( capture groupで囲んでいますが、実際にはここでグループ化するだけで済みます)。これは、自分の|中に交代があるからです。

拡張性と制限

  • 必要に応じて、最初のグループまたは 2 番目のグループにさらに文字列を追加できます。

    ^([abcd]( [xyz])?|[xyz]( [abcd])?)$
    
  • ただし、グループの数を増やしたい場合は、正規表現を使用するのではなく、文字列をスペースで分割し、トークンをループしてグループの順列を見つけることをお勧めします。

于 2013-01-29T12:42:24.730 に答える
1

a正規表現で, b,xを繰り返さずにこれを行う便利な方法はありませんyが、この問題は、事前に宣言された部分式から式を作成することで軽減できます。

このコードは示しています。の最初の 3 行DATAは無効であり、出力で再現されないことに注意してください。

use v5.10;
use warnings;

my $ab = qr/a|b/;
my $xy = qr/x|y/;

my $re = qr/^
(?:
  $ab (?: \s+ $xy)? | $xy (?: \s+ $ab)?
)
$/x;

while (<DATA>) {
  print if /$re/;
}


__DATA__
a b
x y
z z
a
b
x
y
a x
a y
b x
b y
x a
x b
y a 
y b

出力

a
b
x
y
a x
a y
b x
b y
x a
x b
y b
于 2013-01-29T13:03:49.663 に答える
0

これを試して:

^((a|b)( x| y)?|(x|y)( a| b)?)$

正規表現の構造:

# ^            - Line start
# (            - Group start
# (a|b)( x| y) - Match A or B followed by X or Y
# ?            - Where (X|Y) is optional
# |            - Or
# (x|y)( a| b) - Match X or Y followed by A or B
# ?            - Where (A|B) is optional
# )            - And group
# $            - End of line.

これは以下に一致します:

a    y
b    a x
x    y b

だがしかし:

a b
x y
z z
于 2013-01-29T12:36:37.563 に答える
0

単純:

(a|b|x|y|((a|b) (x|y))|((x|y) (a|b)))
于 2013-01-29T12:49:31.237 に答える