ブーストは簡単です。 パート1. Boost.Regex

この記事は、おそらく最高のC ++ライブラリーに捧げる一連の記事の最初の記事です。

この記事では、正規表現に関する次の質問に対処します。





はじめに



私は、正規表現の必要性についての論争に従事したくありません。それぞれが自分自身で決定します。 私の目標は、正規表現を使用したい人のためにBoost.Regexの使いやすさを伝えることでした。 正規表現に慣れていない人のために、少なくともWikipediaを読むことをお勧めします。誰かがそれらをより深く知りたい場合は、 正規表現をマスターすることをお勧めします

Boost.Regexはコンパイルされたライブラリです。つまり、使用するにはコンパイルする必要があります。 これを行う方法は、 「はじめに」に記載されています。

ライブラリを収集することにより、正規表現エンジンで使用される2つのアルゴリズムのいずれかを選択できます:再帰的および非再帰的。 1つ目は高速ですが、スタックオーバーフローが発生する可能性があり、2つ目は少し遅くなりますが安全です。 さまざまなメソッドを定義するためのマクロは、それぞれBOOST_REGEX_RECURSIVEとBOOST_REGEX_NON_RECURSIVEです。 また、各アルゴリズムはわずかにカスタマイズできます。 構成用のマクロとその説明は、 ここで表示できます。

Boost.Regexは、正規表現に対して次のタイプの構文をサポートしています。

  1. Perl(デフォルト)
  2. POSIX拡張
  3. POSIX Basic


「。」(期間)にはデフォルトで「\ n」が含まれていることに注意してください。 これは、対応するアルゴリズムに特別なフラグを渡すことで変更できます。



コアアルゴリズム



ブースト:: regex_match



このアルゴリズムは、着信文字列と何らかの正規表現の対応を確認するために使用され、文字列が一致する場合はtrueを返し、そうでない場合はfalseを返します。

典型的な使用例はregex_match(incoming_string、[match_finding_results]、regular_expression、[flags])です。

オーバーロードされたすべての広告の完全なリストについては、ドキュメントをご覧ください。

その使用例:

std:: string xStr( "AAAA-12222-BBBBB-44455" );

boost::regex xRegEx( "(\\w+)-(\\d+)-(\\w+)-(\\d+)" );

boost::smatch xResults;

std::cout << "==========================Results============================== \n" ;

std::cout << "Does this line match our needs? " << std::boolalpha << boost::regex_match(xStr, xResults, xRegEx) << "\n" ;

std::cout << "Print entire match:\n " << xResults[0] << std::endl;

std::cout << "Print the former string into another format:\n" << xResults[1] << "+"

<< xResults[2] << "+"

<< xResults[3] << "+"

<< xResults[4] << std::endl;




* This source code was highlighted with Source Code Highlighter .






作業の結果は次のようになります。

===========================結果======================= =======

この行は私たちのニーズに合っていますか? 本当

マッチ全体を印刷:

AAAA-12222-BBBBB-44455

前の文字列を別の形式で印刷します。

AAAA + 12222 + BBBBB + 44455



パラメーターを説明するためのアルゴリズムからのわずかな逸脱。 これらのパラメーターはすべてのアルゴリズムで使用されますが、ここでのみ検討します。



match_result_resultsはオプションのパラメーターであり、 match_resultsクラスのオブジェクトにすぎません。 このオブジェクトは、 sub_matchクラスのオブジェクトの配列です。これは、文字列で見つかった対応の最初と最後にある反復子の保護オブジェクトにすぎません。 results_of_finding_は、アルゴリズムの結果を保存するために一致します。 そのため、アルゴリズムが成功した場合、配列のnullメンバーは見つかったすべての一致のsub_matchを格納します(例外は部分一致の使用ですが、それについては後で詳しく説明します)。 配列の後続の各メンバーは、正規表現に含まれる各キャプチャの反復子を格納します。 一致するフラグを使用して、配列の各要素の内容を確認できます。 各sub_matchが反復子をincoming_lineに格納することを覚えておくことが重要です。そのため、一時オブジェクトをソース文字列として渡し、その後アルゴリズムの結果を使用することはできません。 正規表現(たとえば、「(\ w)+」)での再帰的なキャプチャでは、最後のキャプチャのみが結果のmatch_resultに入ります。これは、変更可能なデフォルトの動作です。 すべての再帰キャプチャにアクセスできるようにするには、match_extraフラグを[flags]に渡す必要がありますが、それだけではありません。match_extraを機能させるには、すべての翻訳済みユニットでBOOST_REGEX_MATCH_EXTRAを宣言する必要があります または、boost / regex / user.hppで定義をコメント解除します。 この機能は実験的とラベル付けされており、パフォーマンスが大幅に低下します。 コメントなしの定義でregex_ *アルゴリズムを使用しようとすると、私のVS2008がxutulityの腸でアクセス違反を与えるため、私はそれを試すことができませんでした。 その使用のテストされていない例:

std:: string xStr( "The boost library has a great opportunity for the regex!" );

boost::regex xRegEx( "(\\b\\w{5}\\b)*" );

boost::smatch xResults;

std::cout << "==========================Results============================== \n" ;

if ( boost::regex_search(xStr, xResults, xRegEx, boost::match_extra) )

{

std::cout << "Words consist from exact 5 digits have been found in our line:\n" ;

for ( int j = 0; j < xResults.captures(1).size(); ++j)

std::cout << xResults.captures(1)[j] << std::endl;

}




* This source code was highlighted with Source Code Highlighter .






[フラグ] -オプションのパラメーター。デフォルト値はmatch_defaultです。 利用可能なフラグについては、 こちらをご覧ください 。 フラグは「|」(または)を使用して結合されます。



部分一致



正規表現への部分一致の入力文字列を確認するには、部分一致が必要です。 これは、着信データを非同期で検証する場合や大量のデータを検証する場合、つまり特定の時点で正規表現とソース文字列の完全な対応を実行できない場合に役立ちます。 部分一致を使用するには、match_partialフラグを[flags]に渡す必要があります。 この場合、部分一致が使用されると、使用されるアルゴリズム(regex_match、regex_searchなど)はtrueを返しますが、match_results要素の一致フラグはfalseに設定されます。 部分一致の結果として見つかったものは、同じゼロ要素から取得できます。

使用例:

std:: string xStr( "AAAA-12222" );

boost::regex xRegEx( "(\\w+)-(\\d+)-(\\w+)-(\\d+)" );

boost::smatch xResults;

std::cout << "==========================Results============================== \n" ;

std::cout << "Does this line match the regex? " << std::boolalpha << boost::regex_match(xStr, xResults, xRegEx,

boost::match_default | boost::match_partial) << "\n" ;

std::cout << "Is it the partial match? " << std::boolalpha << !xResults[0].matched << "\nPrint the partial match:\n" << xResults[0] << std::endl;




* This source code was highlighted with Source Code Highlighter .






結論:

===========================結果======================= =======

この行は正規表現と一致しますか? 本当

部分一致ですか? 本当

部分一致を印刷します。

AAAA-12222



regex_search



このアルゴリズムは、特定の正規表現によってソース文字列内の部分文字列を検索するように設計されています。

使用形式は次のとおりです。

regex_search(着信文字列、[結果の一致]、正規表現、[フラグ])

使用例:

std:: string xStr( "The boost library has a great opportunity for the regex!" );

boost::regex xRegEx( "\\b(?:\\w+?)((\\w)\\2)(?:\\w+?)\\b" );

boost::smatch xResults;

std::cout << "==========================Results============================== \n" ;

std:: string ::const_iterator xItStart = xStr.begin();

std:: string ::const_iterator xItEnd = xStr.end();

while ( boost::regex_search(xItStart, xItEnd, xResults, xRegEx) )

{

std::cout << "Word, we've searched, is \"" << xResults[0] << "\". It has two \"" << xResults[2] << "\" inside itself.\n" ;

xItStart = xResults[1].second;

}




* This source code was highlighted with Source Code Highlighter .






結論:

===========================結果======================= =======

私たちが検索した単語は「ブースト」です。 内部に2つの「o」があります。

私たちが検索した単語は「機会」です。 内部に2つの「p」があります。




regex_replace



このアルゴリズムは、正規表現に対応するすべての部分文字列を特定の形式で指定された文字列に置き換えるために使用されます。 結果はイテレータを介して取得でき、引数または戻り文字列として渡されます。 format_no_copyフラグが設定されていない場合、正規表現に一致しない用語の部分は変更されずに出力行にコピーされ、結果として一致した行のみが残ります。 format_first_onlyフラグが渡されると、正規表現に対応する最初のサブストリングのみが置き換えられます。

通常使用される形式:

regex_replace(incoming_string、regular_expression、format_string、[flags])

format_stringは、見つかった部分文字列を置き換える文字列を定義します。

次の構文規則のいずれかに従う場合があります。



使用例:

std:: string xStr( "AAAA-12222-BBBBB-44455" );

boost::regex xRegEx( "(\\w+)-(\\d+)-(\\w+)-(\\d+)" );

std:: string xFormatString( "$1*$2*$3*$4" );

boost::smatch xResults;

std::cout << "==========================Results============================== \n" ;

std::cout << "Print string after replace:\n " << boost::regex_replace(xStr, xRegEx, xFormatString, boost::match_default | boost::format_perl) << std::endl;





* This source code was highlighted with Source Code Highlighter .






結論:

===========================結果======================= =======

置換後に文字列を印刷します。

AAAA * 12222 * BBBBB * 44455





エイズ



regex_iterator



この反復子は、正規表現に対応する部分文字列の出現を順次検索するのに便利です。 増分ごとに、regex_searchを使用して次のサブストリングが検索されます。 イテレータを間接参照する場合、match_results型のオブジェクトを取得します。これにより、必要なすべての情報を取得できます。

使用形式: regex_iterator(start_iterator、end_iterator、regular_expression)

使用例:

std:: string xStr( "AAAA-12222-BBBBB-44455" );

boost::regex xRegEx( "(\\w|\\d)+" );

boost::smatch xResults;

std::cout << "==========================Results============================== \n" ;

boost::sregex_iterator xIt(xStr.begin(), xStr.end(), xRegEx);

boost::sregex_iterator xInvalidIt;

while (xIt != xInvalidIt)

std::cout << *xIt++ << "*" ;




* This source code was highlighted with Source Code Highlighter .






結論:

===========================結果======================= =======

AAAA * 12222 * BBBBB * 44455 *




regex_token_iterator



文字列をトークンに分割するための非常に便利なツール、

使用形式:regex_token_iterator(start_iterator、end_iterator、regular_expression、[submatch])

[submatch]は 、文字列内のトークンの解釈方法を示すために使用されます。

-1の場合、反復子は、正規表現に一致しないシーケンスの部分を返します。 つまり、最初の一致の後に来る文字列が、次の一致の開始まで返されます(最初の一致文字は含まれません)。 または、行の先頭が正規表現を満たさない場合、行の先頭から。 つまり、-1を渡すと、正規表現は区切り文字になります。 0の場合、各反復子オフセット(++)は、「結合」された行の次の部分を示します。つまり、逆参照された各反復子は行キャプチャです。 パラメーターとして正の数値の場合、パラメーターとして渡された数値に対応する正規表現のキャプチャが選択されます。 インデックスの配列をパラメータとして渡すこともできます。その後、イテレータは配列内のインデックスに従って各キャプチャを検索します。つまり、配列が{4、2、1}で構成されている場合、最初のイテレータは4キャプチャを指し、次のイテレータは2を指し、など 指定された正規表現の一致が終了するまで、このプロセスがシーケンス全体で繰り返されます。 デフォルトでは、このパラメーターは0です。

参照解除された反復子は、sub_matchクラスのオブジェクトです。

使用例:

std:: string xStr( "AAAA-12222-BBBBB-44455" );

boost::regex xRegEx( "(\\w|\\d)+" );

boost::smatch xResults;

std::cout << "==========================Results============================== \n" ;

boost::sregex_token_iterator xItFull(xStr.begin(), xStr.end(), xRegEx, 0);

boost::sregex_token_iterator xInvalidIt;

std::cout << "Result the same as the regex_iterator: \n" ;

while (xItFull != xInvalidIt)

std::cout << *xItFull++ << "*" ;

//Parts of captures

boost::regex xRegEx2( "(\\w+)-(\\d+)" );

boost::sregex_token_iterator xItFirstCapture(xStr.begin(), xStr.end(), xRegEx2, 1);

std::cout << "\nShow only first captures: \n" ;

while (xItFirstCapture != xInvalidIt)

std::cout << *xItFirstCapture++ << "*" ;

//Reverse order

int aIndices[] = {2,1};

boost::sregex_token_iterator xItReverseCapture(xStr.begin(), xStr.end(), xRegEx2, aIndices);

std::cout << "\nShow captures in the reverse order: \n" ;

while (xItReverseCapture != xInvalidIt)

std::cout << *xItReverseCapture++ << "*" ;

//Delimiters

boost::regex xRegEx3( "(\\w|\\d)+" );

boost::sregex_token_iterator xItDelimiters(xStr.begin(), xStr.end(), xRegEx3, -1);

std::cout << "\nShow delimiters: \n" ;

while (xItDelimiters != xInvalidIt)

std::cout << *xItDelimiters++ << " " ;




* This source code was highlighted with Source Code Highlighter .






結論:

===========================結果======================= =======

結果はregex_iteratorと同じです:

AAAA * 12222 * BBBBB * 44455 *

最初のキャプチャのみを表示:

AAAA * BBBBB *

キャプチャを逆順に表示します。

12222 * AAAA * 44455 * BBBBB *

区切り文字を表示:

---


発言



N要素の完全一致(一致)のチェックの複雑さがO(N ^ 2)を超え始めた場合、またはスタックオーバーフローの場合(Boost.Regexが再帰モードでビルドされた場合)、どのアルゴリズムもstd :: runtime_errorタイプの例外をスローできます






All Articles