2017-01-21 23 views
1

私は多くの異なるテキストファイルで電子メールを持っており、レイアウトから一貫していないファイルからそれらを抽出する必要があります。私はBoost::RegexBoost::File-systemを試して読んでから、電子メールアドレスを抽出しています。しかし、電子メールの検索や取り出しにはうまくいかないようです。それはemailや手紙aのような簡単な言葉にマッチします。しかし、実際にファイルを読み出すのに問題があるようです。テキストファイルからBoost :: Regexを使って部分文字列を抽出する

最小限例は以下のように(なしが含まれます)で次のように電子メールのサンプルを使用できます:働いていない理由を私はよく分からない

#include <fstream> 
#include <iostream> 
#include <sstream> 
#include <string> 

#include <boost/regex.hpp> 
#include <boost/foreach.hpp> 
#include <boost/filesystem.hpp> 


namespace fs = boost::filesystem; // File system is namespace. 

int main() { 
    boost::regex pattern("\b[A-Z0-9._%+-][email protected][A-Z0-9.-]+\.[A-Z]{2,}\b"); // Email regex to match. 
    boost::smatch result; 

    fs::path targetDir(boost::filesystem::current_path()); // Look in this folder. 
    fs::directory_iterator it(targetDir), eod;  // Iterate over all the files in said directory. 
    std::string line; 
    BOOST_FOREACH(fs::path const &p, std::make_pair(it, eod)) { // Actual iteration. 
     if (fs::is_regular_file(p)) { // What this does is checks if it's a normal file. 
      std::ifstream infile(p.string()); // Read file line by line. 
      if (p.string().substr(p.string().length() - 3) != "txt") { 
       continue; // Skip to next file if not text file. 
      } 
      while (std::getline(infile, line)) { 
       bool isMatchFound = boost::regex_search(line, result, pattern); 
       if (isMatchFound) 
       { 
        for (unsigned int i = 0; i < result.size(); i++) 
        { 
         std::cout << result[i] << std::endl; 
        } 
       } 
      } 
      infile.close(); 
     }  
    } 
    return 0; 
} 

"[email protected]","S" 
"[email protected]","R" 
[email protected]<br> 

そして、電子メールがテキストファイル内にあることができるさまざまな方法、この正規表現をどのようにして一致させるのですか?

答えて

3

正規表現に瑕疵があります。

enter image description here

また、\.は違法なエスケープシーケンスであるので、あなたのコンパイラが警告している必要があります。\bは何かを意味します。 (あなたは\\.が必要です)

最後に、\bはPerlと互換性のある正規表現ですと思います。ああ、大文字のメールを欲しかっただけではありませんでした。だから、それを修正することができます:

boost::regex pattern("\\b[A-Z0-9._%+-][email protected][A-Z0-9.-]+\\.[A-Z]{2,}\\b", 
    boost::regex_constants::perl | boost::regex_constants::icase); // Email regex to match. 

おそらくRFC822パーサライブラリを使用するために少し良いだろう:)

ここでは、コードのクリーン作品です:

#include <boost/filesystem.hpp> 
#include <boost/range/iterator_range.hpp> 
#include <boost/regex.hpp> 
#include <fstream> 
#include <iostream> 
namespace fs = boost::filesystem; 

int main() { 
    boost::regex pattern("\\b[A-Z0-9._%+-][email protected][A-Z0-9.-]+\\.[A-Z]{2,}\\b", 
     boost::regex_constants::perl | boost::regex_constants::icase); // Email regex to match. 
    boost::smatch result; 
    std::string line; 

    for (fs::path p : boost::make_iterator_range(fs::directory_iterator("."), {})) { 
     if (!fs::is_regular_file(p) || p.extension() != ".txt") 
      continue; 

     std::cerr << "Reading " << p << "\n"; 

     std::ifstream infile(p.string()); // Read file line by line 
     while (std::getline(infile, line)) { 
      if (boost::regex_search(line, result, pattern)) { 
       std::cout << "\t" << result.str() << "\n"; 
      } 
     } 
    }  
} 

注:

  • ブーストファイルシステムを使用する場合は、extension()アクセサー機能を使用する代わりに、欠陥のある文字列操作は行いません
  • あなたがそれらを使用していないので、ファイルの冗長終値(これはC++で、彼らはスコープの外に出たときに近いファイル)
  • は、部分マッチグループを気にしません可能
  • 場合の条件のネストを減らします

    Reading "./input.txt" 
        [email protected] 
        [email protected] 
        [email protected] 
    Reading "./output.txt" 
    Reading "./big.txt" 
    Reading "./CMakeLists.txt" 
    Reading "./CMakeCache.txt" 
    
    :それは(stderrを含む)は、プリント私のテストフォルダに
  • プリント試合のstr()

関連する問題