2017-09-06 3 views
3

を認識しません:

ifstream file_stream("commented.cpp",ifstream::binary); 

std::string txt((std::istreambuf_iterator<char>(file_stream)), 
std::istreambuf_iterator<char>()); 

cmatch m; 
bool result = regex_search(txt.c_str(), m, regex("^#(\S*)$",regex_constants::basic)); 

ファイルには、交​​流電源であり、それはラインで始まります

#include <stdio.h> 

私はディレクティブを解析しようとしていますが、regexbuddyでregexpをチェックしましたが、100%で動作しますが、std :: regexでregex_searchはfalseを返します。 $文字はgettincは認識されず、posix構文の場合は^と思われます。 ECMAScriptを使用しようとしましたが、正規表現は、$シンボルを削除した場合にのみ動作します。

//ecmascript syntax 
bool result = regex_search(txt.c_str(), m, regex("^#(\S*)")); 

ファイルがバイナリフラグを使用して読んで、そうtxt文字列は、$構文のために必要とされるすべての\r\nの文字を保持しています。私は、この問題を解決する方法を助けます。

+4

しかし '^#(\ S *)$' _doesn't_一致 'の#include '。 '\ S'は空白以外のものにしかマッチしません。 '#include 'に空白があり、 '$'は行末にアンカーしたいので、 '#include'をその正規表現とマッチさせることはできません。 –

答えて

1

ほとんどの場合、$アンカーは、文字列の終わり(入力全体)アンカーとしてのみ機能することに注意してください。 this threadを参照してください。肯定先読みに基づくカスタム境界パターン(?=$|\r?\n)を使用して、$を行位置の末尾に一致させることができます。

もう1つの問題は、通常の文字列リテラルで\Sエスケープシーケンスを使用していることです。つまり、空白以外のパターンではなく、Sの文字として扱われます。 1つの\を使用して、正規表現エスケープシーケンス(\エスケープdsなどはリテラルのバックスラッシュである必要があります)を定義するために生の文字列リテラルを使用してください。または、通常の文字列リテラルでdouble \をエスケープします。

また、@HWaltersはすでに^#\S+$#include <stdio.h>と一致しないことに気付いたので、内部のスペースを考慮する必要があります。したがって正規表現は^#include[ \t]+(\S+)(?=$|\r?\n)のように見え、#include、次にいくつかの水平スペースがあることを確認してから、空白文字以外の任意の数字(ここでは1つ以上、+)を文字列の最後または改行(CRLFまたはLF)。ここ

snippetです:

regex r(R"(^#include[ \t]+(\S+)(?=$|\r?\n))"); 
string s("#include <stdio.h>\r\n#include <regex>"); 
smatch m; 
if (regex_search(s, m, r)) { 
    std::cout << m[1] << std::endl; 
} 
関連する問題