m文字以内を表す{,m}なんて量指定子は存在しない。…わけではない。

# 結論

通常?多くの言語で使える正規表現では`{,m}`は使えず、`{0,m}`,`{1,m}`を使う必要がある。

が、
(いまのところ見つけられた範囲では)
Rubyやvimなどでは`{,m}`の書き方が使える。

~~正規表現エンジンで言うと、
鬼車系とNFAが該当するようだ。~~

***

引用記事です。

# 発端

n文字以内を指定したくて、Googleで「正規表現　以内」で検索。
出てきたページ
[正規表現：文字数や、文字数の範囲を指定する表現 | WWWクリエイターズ](http://www-creators.com/archives/3776)
を参照。

>「〜文字以下」の指定
>
同様に最小値の指定を省けば、「〜文字以下」の表現となります。
>
```php
// 10文字以下の半角数字の表現
[0-9]{,10}
```

という記法を発見。
特に言語指定がされていなかったので、一般的な正規表現と思い込む。

サンプルにならい、JavaScriptの正規表現に組み込んだところ、うまく一致しない。

[Online regex tester and debugger: PHP, PCRE, Python, Golang and JavaScript](https://regex101.com/)

でチェックしてみても、どうやら正しく動いていないようだ。

# JavaScript

[正規表現 - JavaScript#特殊文字の使い方 | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Regular_Expressions#Using_Special_Characters)

ここには`{,n}`の記述がなかった。
なので、先のサンプルは少なくともJSでは存在しない記法だと考えた。

***

ではあのサンプルは何でチェックしていたのか？ソラで書いてミスしてしまったものなのか？
卑近な言語の量指定子をついでにチェックしてみた。

# Perl

正規表現と言えばPerl。[^1]

[perlreref - Perl の正規表現のリファレンス#量指定子 - perldoc.jp](http://perldoc.jp/docs/perl/5.16.1/perlreref.pod#QUANTIFIERS)

>{,n} という量指定子はありません。 これはリテラルな文字列として扱われます。

釘を刺されていた。

# Python
[6.2. re — 正規表現操作#正規表現のシンタックス — Python 3.6.5 ドキュメント](https://docs.python.jp/3/library/re.html#regular-expression-syntax)

ないです。

# PHP

PHPはPerl互換のPCREとPOSIX正規表現なので、POSIXのほうを

[PHP: 繰り返し - Manual](http://php.net/manual/ja/regexp.reference.repetition.php)

PCREはPerl互換なので見るほどでもなかったかも。

[PHP: Perl とは異なる点 - Manual](http://php.net/manual/ja/reference.pcre.pattern.differences.php)

[PHP: POSIX 正規表現との違い - Manual](http://php.net/manual/ja/reference.pcre.pattern.posix.php)

POSIXの方も指摘されてないので違いはない？

# Wiki

[正規表現 - Wikipedia](https://ja.wikipedia.org/wiki/%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7%8F%BE)

意外と充実してわかりやすそうですが、ない。

# その他

[正規表現メモ](http://www.kt.rim.or.jp/~kbk/regex/regex.html)

`,n`, `,m`でチェックしましたが、なさそう。

# Ruby

はい、もったいぶりましたが、あるパターン。

[正規表現 (Ruby 2.5.0)](https://docs.ruby-lang.org/ja/latest/doc/spec=2fregexp.html)

(バージョン古い？)

>{,m} m回以下(mは数字)

あ り ま し た。

# 正規表現エンジンを調べる

Rubyの正規表現のエンジンはなんじゃろと検索すると、

[Ruby 2.4.1新機能: Onigmo正規表現の非包含演算子(?~ )をチェック](https://techracho.bpsinc.jp/hachi8833/2017_03_23/37689/)

>Rubyの正規表現エンジンとしておなじみのOnigmo

Onigurumaの派生です。

[鬼車 正規表現 Version 6.0.0    2016/05/02](https://ttssh2.osdn.jp/manual/ja/reference/RE.txt)

[Onigmo/RE.ja at master · k-takata/Onigmo](https://github.com/k-takata/Onigmo/blob/master/doc/RE.ja)

>{,n}    零回以上n回以下 ({0,n})
>{,n}?   零回以上n回以下 (== {0,n}?)

なるほどー。

# Vim

なんとなくカバーしてそうだったので記事を書くついでに調べました。

[vim正規表現リファレンス#繰返し制御系（量指定子） - Qiita](https://qiita.com/kawaz/items/d0708a4ab08e572f38f3#%E7%B9%B0%E8%BF%94%E3%81%97%E5%88%B6%E5%BE%A1%E7%B3%BB%E9%87%8F%E6%8C%87%E5%AE%9A%E5%AD%90)

>`a\{,m}` は `0` 回以上 `m` 回以下の `a` の繰り返しにマッチする。（最長マッチ）

やはりある。

## エンジン調べ

[pattern#two-engines - Vim日本語ドキュメント](https://vim-jp.org/vimdoc-ja/pattern.html#two-engines)

>Vim は二つの正規表現エンジンを持っています:
1. 古い、バックトラッキングエンジン。すべての機能をサポート。
2. 新しい、NFA エンジン。いくつかのパターンで動作が速いがいくつかのパターンで
   は遅くなる。
>
Vim は自動的に適切なエンジンを選択します。何か問題が発生したか、あるいは明示的
にエンジンを選択したいか、あるいはその他の理由で、エンジンを指定したい場合はパ
ターンの先頭で次のように指定します:

[pattern#E60 - Vim日本語ドキュメント](https://vim-jp.org/vimdoc-ja/pattern.html#E60)

>`\{,m}`   アトムの 0 以上 m 以下の繰り返し。最長一致
>`\{-,m}`  アトムの 0 以上 m 以下の繰り返し。最短一致

なるほど、Vimは最長と最短別々の記法があると。

>{すべてViにはない機能です}

さすが。

### ~~NFAエンジン~~

**追記:**コメントにあるように以下リンクはVimのものの解説ではありません。

[正規表現の詳細仕様（ＮＦＡエンジン）](http://www.venus.dti.ne.jp/mw31/apsaly/RegexNFA.html)

>　反復子の {n,m} には、以下のような省略型も存在します。
>　　　{n} 　　n 回丁度（ n >= 0 ）
>　　　{n,} 　　n 回以上（ n >= 0 ）
>　　　{,m} 　　0 回以上 m 回以下（ m >= 0 ）

Vimのほうがさらに拡張されているようだ。

# おわり

正規表現を話題にするときは、何の言語(エンジン)を使っているかを少し意識しましょう。
やはり動作環境の掲示は大事。



[^1]: 個人の感想です。