ファイルへの/からの正規表現のシリアライズ/デシリアライズおよび保存/ロードは可能ですか?
いくつかの正規表現を構築する非常に時間のかかるプロセスがあり、それらを保存してロードすることで時間を節約できるかどうか疑問に思っています。
いいえ、とにかく正規表現を再コンパイルする必要があるため、おそらく不可能です。
ただし、boost::xpressive を使用すると、正規表現の式テンプレート構築を介して、コンパイル時に正規表現のコンパイルを実行できます。これにより、正規表現のコンパイル時間が完全になくなります。
ただし、余分な時間の使用の真の原因は、ほぼ確実に、バックトラッキング正規表現エンジンを使用して IE の正規表現を不適切に使用していることです。
RE2は、バックトラッキングを使用しない従来の自動正規表現エンジンですが、代わりに NFA または DFA を直接構築します。後方参照や多くの非正規表現ベースの「機能」を使用していない場合、RE2 を使用すると、多くのコーナー ケースで速度が大幅に向上します。
これらの機能を使用している場合は、それらがマッチングの速度を厳密に支配することに注意する必要があります。これらの機能は、排除しようとしている速度低下の主な原因であることはほぼ確実です。
boost::regexをシリアライズできます:
#include <string>
#include <iostream>
#include <sstream>
#include <boost/regex.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/split_free.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
namespace boost
{
namespace serialization
{
template<class Archive, class charT, class traits>
inline void save(Archive & ar,
const boost::basic_regex<charT, traits> & t,
const unsigned int /* file_version */)
{
std::basic_string<charT> str = t.str();
typename boost::basic_regex<charT, traits>::flag_type flags = t.flags();
// typename boost::basic_regex<charT, traits>::locale_type loc = t.getloc();
ar & str;
ar & flags;
// ar & loc;
}
template<class Archive, class charT, class traits>
inline void load(Archive & ar,
boost::basic_regex<charT, traits> & t,
const unsigned int /* file_version */)
{
std::basic_string<charT> str;
typename boost::basic_regex<charT, traits>::flag_type flags;
// typename boost::basic_regex<charT, traits>::locale_type loc;
ar & str;
ar & flags;
// ar & loc;
t.assign(str, flags);
// t.imbue(loc);
}
template<class Archive, class charT, class traits>
inline void serialize(Archive & ar,
boost::basic_regex<charT, traits> & t,
const unsigned int file_version)
{
boost::serialization::split_free(ar, t, file_version);
}
}
}
int main(int argc, char ** argv)
{
std::stringstream os;
{
boost::regex re("<a\\s+href=\"([\\-:\\w\\d\\.\\/]+)\">");
boost::archive::text_oarchive oar(os);
oar & re;
}
os.seekg(std::ios_base::beg);
boost::regex re;
boost::cmatch matches;
boost::archive::text_iarchive iar(os);
iar & re;
boost::regex_search("<a href=\"https://stackoverflow.com/questions/18752807/save-serialize-boost-or-std-regexes\">example</a>", matches, re);
std::cout << matches[1] << std::endl;
}
ただし、これは、文字列から正規表現を再構築するよりもパフォーマンスが向上するという意味ではありません。
注: 簡単にするために std::locale のものを省略しました