結論
通常?多くの言語で使える正規表現では{,m}
は使えず、{0,m}
,{1,m}
を使う必要がある。
が、
(いまのところ見つけられた範囲では)
Rubyやvimなどでは{,m}
の書き方が使える。
正規表現エンジンで言うと、
鬼車系とNFAが該当するようだ。
引用記事です。
発端
n文字以内を指定したくて、Googleで「正規表現 以内」で検索。
出てきたページ
正規表現:文字数や、文字数の範囲を指定する表現 | WWWクリエイターズ
を参照。
「〜文字以下」の指定
同様に最小値の指定を省けば、「〜文字以下」の表現となります。
// 10文字以下の半角数字の表現
[0-9]{,10}
という記法を発見。
特に言語指定がされていなかったので、一般的な正規表現と思い込む。
サンプルにならい、JavaScriptの正規表現に組み込んだところ、うまく一致しない。
Online regex tester and debugger: PHP, PCRE, Python, Golang and JavaScript
でチェックしてみても、どうやら正しく動いていないようだ。
JavaScript
正規表現 - JavaScript#特殊文字の使い方 | MDN
ここには{,n}
の記述がなかった。
なので、先のサンプルは少なくともJSでは存在しない記法だと考えた。
ではあのサンプルは何でチェックしていたのか?ソラで書いてミスしてしまったものなのか?
卑近な言語の量指定子をついでにチェックしてみた。
Perl
正規表現と言えばPerl。1
perlreref - Perl の正規表現のリファレンス#量指定子 - perldoc.jp
{,n} という量指定子はありません。 これはリテラルな文字列として扱われます。
釘を刺されていた。
Python
6.2. re — 正規表現操作#正規表現のシンタックス — Python 3.6.5 ドキュメント
ないです。
PHP
PHPはPerl互換のPCREとPOSIX正規表現なので、POSIXのほうを
PCREはPerl互換なので見るほどでもなかったかも。
POSIXの方も指摘されてないので違いはない?
Wiki
意外と充実してわかりやすそうですが、ない。
その他
,n
, ,m
でチェックしましたが、なさそう。
Ruby
はい、もったいぶりましたが、あるパターン。
(バージョン古い?)
{,m} m回以下(mは数字)
あ り ま し た。
正規表現エンジンを調べる
Rubyの正規表現のエンジンはなんじゃろと検索すると、
Ruby 2.4.1新機能: Onigmo正規表現の非包含演算子(?~ )をチェック
Rubyの正規表現エンジンとしておなじみのOnigmo
Onigurumaの派生です。
鬼車 正規表現 Version 6.0.0 2016/05/02
Onigmo/RE.ja at master · k-takata/Onigmo
{,n} 零回以上n回以下 ({0,n})
{,n}? 零回以上n回以下 (== {0,n}?)
なるほどー。
Vim
なんとなくカバーしてそうだったので記事を書くついでに調べました。
vim正規表現リファレンス#繰返し制御系(量指定子) - Qiita
a\{,m}
は0
回以上m
回以下のa
の繰り返しにマッチする。(最長マッチ)
やはりある。
エンジン調べ
pattern#two-engines - Vim日本語ドキュメント
Vim は二つの正規表現エンジンを持っています:
- 古い、バックトラッキングエンジン。すべての機能をサポート。
- 新しい、NFA エンジン。いくつかのパターンで動作が速いがいくつかのパターンで
は遅くなる。
Vim は自動的に適切なエンジンを選択します。何か問題が発生したか、あるいは明示的
にエンジンを選択したいか、あるいはその他の理由で、エンジンを指定したい場合はパ
ターンの先頭で次のように指定します:
\{,m}
アトムの 0 以上 m 以下の繰り返し。最長一致
\{-,m}
アトムの 0 以上 m 以下の繰り返し。最短一致
なるほど、Vimは最長と最短別々の記法があると。
{すべてViにはない機能です}
さすが。
NFAエンジン
**追記:**コメントにあるように以下リンクはVimのものの解説ではありません。
反復子の {n,m} には、以下のような省略型も存在します。
{n} n 回丁度( n >= 0 )
{n,} n 回以上( n >= 0 )
{,m} 0 回以上 m 回以下( m >= 0 )
Vimのほうがさらに拡張されているようだ。
おわり
正規表現を話題にするときは、何の言語(エンジン)を使っているかを少し意識しましょう。
やはり動作環境の掲示は大事。
-
個人の感想です。 ↩