2009-08-25 11 views
2

たとえば、タイトルに記載されているフォーマットで時間を見つけなければなりません(ただし、%タグの順序は異なる可能性があります)"The date is 2009-August-25."どのようにプログラムをタグに埋め込み、どのような構造を日付文字列の特定の部分をどのように動作させるかについての情報とともに格納するために使用する方が良いでしょうか?マスクを持つ文字列を解析する必要があります(この "%yr-%mh-%dy"のような)ので、int値を取得します

答えて

1

最初にboost::date_timeライブラリを参照してください。それはIO system魔女があなたが欲しいものかもしれないが、私は検索の欠如を参照してください。

カスタム検索を行うにはboost::xpressiveが必要です。それはあなたが必要とするものを含んでいます。私の急いで嘆いた例を見てみましょう。まず、カスタムパターンを解析する必要があります.Xpressiveでは簡単です。あなたが必要とするヘッダを初めて目:

#include <string> 
#include <iostream> 
#include <map> 
#include <boost/xpressive/xpressive_static.hpp> 
#include <boost/xpressive/regex_actions.hpp> 

//make example shorter but less clear 
using namespace boost::xpressive; 

第二には、あなたの特別なタグのマップを定義します。

std::map<std::string, int > number_map; 
number_map["%yr"] = 0; 
number_map["%mh"] = 1; 
number_map["%dy"] = 2; 
number_map["%%"] = 3; // escape a % 

次のステップは、正規表現魔女はタグで私たちのパターンを解析し、変数にマップから値を保存します作成することです

int tag_id; 
sregex rx=((a1=number_map)|(s1=+~as_xpr('%')))[ref(tag_id)=(a1|-1)]; 

詳しい情報や説明を見herehereを:それはタグを見つけるか、セーブ-1それ以外TAG_ID。

std::string pattern("%yr-%mh-%dy"); // this will be parsed 

    sregex_token_iterator begin(pattern.begin(), pattern.end(), rx), end; 
    if(begin == end) throw std::runtime_error("The pattern is empty!"); 

sregex_token_iteratorが私たちのトークンを反復処理し、それぞれの時間は、それがTAG_ID varibleを設定します: は今、いくつかのパターンを解析することができます。このトークンを使って正規表現を構築するだけです。私たちは、アレイ内で定義された静的正規表現のタグ対応する部品を使用してこの正規表現を構築します:

sregex regex_group[] = { 
    range('1','9') >> repeat<3,3>(_d), // 4 digit year 
    as_xpr("January") | "February" | "August", // not all month XD so lazy 
    repeat<2,2>(range('0','9'))[ // two digit day 
    check(as<int>(_) >= 1 && as<int>(_) <= 31) ], //only bettwen 1 and 31 
    as_xpr('%') // match escaped % 
}; 

は最後に、私たちの特別な正規表現を構築し始めることができます。最初の試合では最初の試合が始まります。タグが一致したとTAG_IDたちは、アレイから正規表現を選択する非負であるされている場合は、それ以外の試合はおそらく、区切り文字であり、我々はそれに一致する正規表現魔女の構築:

sregex custom_regex = (tag_id>=0) ? regex_group[tag_id] : as_xpr(begin->str()); 

次の我々は次の正規表現を終了し、追加し始めから繰り返されます:

while(++begin != end) 
{ 
    if(tag_id>=0) 
    { 
     sregex nextregex = custom_regex >> regex_group[tag_id]; 
     custom_regex = nextregex; 
    } 
    else 
    { 
     sregex nextregex = custom_regex >> as_xpr(begin->str()); 
     custom_regex = nextregex; 
    } 
} 

今私達の正規表現は準備ができている、いくつかの日付を見つけることができます: - ]

std::string input = "The date is 2009-August-25."; 

smatch mydate; 
if(regex_search(input, mydate, custom_regex)) 
    std::cout << "Found " << mydate.str() << "." << std::endl; 

をxpressiveライブラリは非常に強力かつ高速です。それはパターンの美しい使用です。

あなたは、この例のように、私はコメントやポイント;-)

に知らせた場合
1

私はタグ付き文字列を正規表現で変換し、3つのフィールドのキャプチャと検索します。正規表現の複雑さは、あなたが%yrに対して受け入れたいものによって決まります。あまり厳密でない式を使用して有効な値を確認することもできます。これにより、より正確なエラーメッセージ(「日付が見つかりません」の代わりに「無効な月:Augsut」)またはコンテキストに応じて誤検出につながる可能性があります。

関連する問題