web-dev-qa-db-ja.com

正規表現での+の意味は何ですか?

正規表現のプラス記号はどういう意味ですか?

33
NoodleOfDeath

+は、コンテキストに応じて、実際には2つの意味を持つことができます。

上記の他の回答と同様に、+は通常 repetition 演算子であり、前のトークンを1回以上繰り返します。 a+形式言語理論 ではaa*として表現され、a{1,}として表現することもできます(最小で1回、最大で無限回一致)。


ただし、+は、反復演算子(?+*+++または{m,n}+)の後に続く場合、他の数量詞 possessive を作成することもできます。所有的量指定子は、一部の正規表現フレーバー(PCRE、JavaおよびJGsoftエンジン)の高度な機能であり、一致が行われるとエンジンをバックトラックしないように指示します。

これがどのように機能するかを理解するには、正規表現エンジンの2つの概念を理解する必要があります:greedinessbacktracking。貪欲さは、一般的な正規表現ができるだけ多くの文字を消費しようとすることを意味します。私たちのパターンが.*であるとしましょう( dot は正規表現の特別な構成で、任意の文字を意味します1;星は0回以上一致することを意味します)、ターゲットはaaaaaaaabです。文字列全体がパターンを満たす最長の一致であるため、文字列全体が消費されます。

ただし、パターンを.*bに変更するとします。これで、正規表現エンジンがaaaaaaaabと照合しようとすると、.*が再び文字列全体を消費します。ただし、エンジンは文字列の終わりに達し、パターンはまだ満たされていないため(.*はすべてを消費しますが、パターンは引き続きbに一致する必要があります)、それはbacktrack、一度に1文字、bと一致させます。最初のバックトラックは.*aaaaaaaaを消費させ、次にbbを消費させ、パターンは成功します。

所有量指定子も貪欲ですが、前述のように、いったん一致を返すと、エンジンはそのポイントを超えてバックトラックできなくなります。したがって、パターンを.*+bに変更し(任意の文字を0回以上一致させ、その後にbを続けて)、aaaaaaaabと一致させようとすると、.*は文字列全体を消費します。しかし、それは所有的であるため、バックトラック情報は破棄され、bは一致しないため、パターンは失敗します。


1 ほとんどのエンジンでは、/s( "singleline"または "dotall") modifier が指定されていない限り、ドットは改行文字と一致しません。

59

ほとんどの実装では+は「1つ以上」を意味します。

いくつかの理論的な著作では+は「または」を意味するために使用されます(ほとんどの実装では|そのための記号)。

12
sepp2k

前の式の1つ以上。

[0-9]+

一致します:

1234567890

に:

私は1234567890ドルを持っています

6
Chris

前述のシンボルの1つ以上の出現。

例えば。 a+は、文字aを1回以上意味します。したがって、aaaaaaaaaaに一致しますが、空の文字列には一致しません。

アスタリスク(*)は、あなたが(exp)+ なので (exp)(exp)*、 どこ (exp)は任意の正規表現です。

3
phimuemue