28

他の2つの間の部分文字列を抽出したいと思います。
例:/home/toto/FILE_mysymbol_EVENT.DAT
またはちょうどFILE_othersymbol_EVENT.DAT
そして私は取得したい:mysymbolothersymbol

Boostや他のライブラリを使いたくありません。CERNのROOTlibを除いて、 TRegexpを使用したC ++の標準的なものですが、使用方法がわかりません...

4

4 に答える 4

51

昨年から、C++には正規表現が標準に組み込まれています。このプログラムは、それらを使用して、目的の文字列を抽出する方法を示します。

#include <regex>
#include <iostream>

int main()
{
    const std::string s = "/home/toto/FILE_mysymbol_EVENT.DAT";
    std::regex rgx(".*FILE_(\\w+)_EVENT\\.DAT.*");
    std::smatch match;

    if (std::regex_search(s.begin(), s.end(), match, rgx))
        std::cout << "match: " << match[1] << '\n';
}

次のように出力されます。

一致:mysymbol

ただし、正規表現のライブラリサポートがあまり良くないため、GCCでは機能しないことに注意してください。VS2010(およびおそらくVS2012)でうまく機能し、clangで機能するはずです。


現在(2016年後半)までに、すべての最新のC++コンパイラとその標準ライブラリはC++ 11標準で完全に最新であり、すべてではないにしてもほとんどのC++14も同様です。GCC6と今後のClang4は、今後のC++17標準のほとんどもサポートします。

于 2012-07-24T11:21:13.920 に答える
3

TRegexpは、他の正規表現フレーバーと比較して、非常に限られた正規表現のサブセットのみをサポートします。これにより、ニーズに合った単一の正規表現を作成するのがやや厄介になります。

考えられる解決策の1つ:

[^_]*_([^_]*)_

最初のアンダースコアまで文字列と一致し、次のアンダースコアまですべての文字をキャプチャします。試合の関連する結果は、グループ番号1にあります。

しかし、あなたの場合、なぜ正規表現を使用するのですか?文字列内で区切り文字の最初と2番目の出現箇所を見つけて、_それらの位置の間の文字を抽出するだけです。

于 2012-07-24T09:04:02.390 に答える
3

正規表現を使用する場合は、C ++ 11の正規表現を使用することをお勧めします。まだサポートしていないコンパイラがある場合は、Boostを使用することをお勧めします。Boostは、私がほぼ標準のC++の一部と見なしているものです。

しかし、この特定の質問については、正規表現の形式は実際には必要ありません。適切なエラーチェック(など)をすべて追加し、コードをテストして、タイプミスを削除すると、このスケッチのようなものは問題なく機能するはずbeg != nposですend != npos

std::string between(std::string const &in,
                    std::string const &before, std::string const &after) {
  size_type beg = in.find(before);
  beg += before.size();
  size_type end = in.find(after, beg);
  return in.substr(beg, end-beg);
}

明らかに、をstd::stringテンプレートパラメータに変更することができ、それは、std::wstringまたはほとんど使用されないのインスタンス化でも問題なく機能するはずstd::basic_stringです。

于 2012-07-24T09:25:56.047 に答える
0

私はそれを信頼する前にコーナーケースを研究しました。

しかし、これは良い候補です:

std::string text = "/home/toto/FILE_mysymbol_EVENT.DAT";
std::regex reg("(.*)(FILE_)(.*)(_EVENT.DAT)(.*)");
std::cout << std::regex_replace(text, reg, "$3") << '\n';
于 2020-02-14T21:15:54.510 に答える