1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

正規表現の「または」OR句について

Posted at

正規表現の「または」or句について

**「|」(パイプ)**は、「どちらかにマッチ」だと思うけど、順番があるので注意

普通の IF 文などの論理演算の OR と同じだと早合点してしまうと、順番なんかどうでもいいや、と思いがちだけど、正規表現の場合は、順番も重要になるので、注意。

例えば、

ababc」という文字列をターゲットにする

これに対して、以下の正規表現を考える

(([a-b])|(abc))+

意味は、『a~bまでの文字、または「abc」という文字列』 が、1文字以上の領域。

マッチ文字列は、「abab

最後の「c」がマッチしない

一方、順番を逆にした以下の正規表現を考えると、

((abc)|([a-b]))+

マッチ文字列は、「ababc

最後の「c」も含まれる

つまり、「(([a-b])|(abc))+」の正規表現の処理としては、

先頭の1文字目は「a」で[a-c]の表現にマッチ、2文字目も[a-c]でマッチ、3文字目も[a-c]でマッチ、4文字目も[a-c]でマッチ、5文字目は「c」なので、[a-b]ではマッチしないので、次の表現「abc」に遷移するもののマッチしない(「c」という表現では「abc」とマッチしない)。

マッチしなかった時に、n文字までマッチしていたものをn-1文字(n-m文字)に戻ってマッチしなおす。という事はしない。

一方、「((abc)|([a-b]))+」の場合は、

先頭の1文字目は「a」は「abc」でひとまず仮マッチするので、続けて1+1=2文字目は「b」なので、さらに継続して、1+2=3文字目は「a」なのでマッチしないので、1文字目からの「aba」は「abc」にマッチしないという事で、1文字に戻って、次の表現「a-b」でマッチ。2文字目も[a-b]でマッチ。3文字目は「a」なので、最初の表現「abc」にひとまず仮マッチで、次の文字、その次の文字とあわせて「abc」なので、完全にマッチ。・・・という事で、マッチした文字列は「ababc」となる。

...という流れを考えてみると分かりやすいかもしれない。

以上

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?