web-dev-qa-db-ja.com

std :: regexのコンパイル時間の蓄積

私は自分のプロジェクトでstd::regexを使用しています。私はコンパイル時に正規表現を知っており、正規表現の構築はO(2 ^ m)にあり、mは正規表現の長さであるため、コンパイル時に正規表現を構築したいと思います。これはstd :: regexで可能ですか?(basic_regexのc​​onstexprctorが表示されないため、そうは思いません)そして、そうでない場合は、コンパイル時に正規表現を構築できる正規表現ライブラリがあります

13
Exagon

HanaDusikovaによるCppCon2017ライトニングトーク "Regular Expressions Redefined in C++" は、正規表現文字列のユーザー定義リテラルを使用したコンパイル時の正規表現へのアプローチと、マッチングを生成するためのコンパイル時のアプローチについて説明しました。関数。 コードはGitHubにあります ですが、現時点ではまだ実験的で非常に流動的です。したがって、コンパイル時の正規表現はおそらく近いうちに表示されるようです。

10
legalize

programコンパイルとregexコンパイルを区別する必要があります。後者は実際にはプログラムの実行時に行われ、さまざまな文字列との高速マッチングに適した、大きくて効率的な構造(ステートマシン)を構築することを意味します。

c ++ 11正規表現では、文字列の正規表現オブジェクトを作成すると、正規表現のコンパイルが行われます。

std::regex e (your_re_string);

このようなオブジェクトをregex_matchregex_searchregex_replaceで使用する場合は、コンパイル済みの正規表現を使用することを利用できます。したがって、プログラムのコンパイル時に文字列がわかっている場合、速度を上げるためにできる最善のことは、プログラムの実行ごとに1回だけ対応する正規表現オブジェクトを作成することです。たとえば、初期化子を使用して静的変数として宣言します。

static  std::regex e (your_constant_re_string);

おそらくそれはあなたが望むものです。

regex_match、...関数の一部の形式は、代わりに正規表現文字列ですぐに機能する場合があります。ただし、通常はプログラマーにとっては便利ですが、それらを使用すると、そのような関数が呼び出されるたびに正規表現のコンパイルを実行するとパフォーマンスが低下することに注意してください。

P.S.プログラムのコンパイル時に正規表現をコンパイルしてもらいたい場合は、(1)外部の正規表現/レクサーコンパイラソフトウェア( https://github.com/madelson/PrecompiledRegexなど)を使用できます。 Fody 、Flex https://en.wikipedia.org/wiki/Flex_(lexical_analyser_generator) または同様の)(2)std::regexオブジェクトをコンパイルしてから、シリアル化してC++に変換します入力(実際には(1)のDIYバージョンです)しかし、プログラムの実行ごとに1つの正規表現コンパイルを保存するためだけに必要な場合は価値がないと確信しています。本当に圧倒的な表現がない限り。

5