web-dev-qa-db-ja.com

C ++ 11 regexライブラリと一致する正規表現グループ

グループマッチングに正規表現を使用しようとしています。 1つの大きな文字列から2つの文字列を抽出します。

入力文字列は次のようになります。

tХB:[email protected] Connected
tХB:[email protected] WEBMSG #Username :this is a message
tХB:[email protected] Status: visible

Usernameは何でもかまいません。終わりの部分this is a messageも同様です。

私がやりたいことは、シャープ記号#の後に続くUsernameを抽出することです。文字列の他の場所からのものではありません。また、セミコロン:の後に続く文字列からmessageを取得したいと考えています。

以下の正規表現で試してみました。ただし、結果は出力されません。

regex rgx("WEBMSG #([a-zA-Z0-9]) :(.*?)");
smatch matches;

for(size_t i=0; i<matches.size(); ++i) {
    cout << "MATCH: " << matches[i] << endl;
}

一致しません。私の正規表現の何が問題になっていますか?

14
Vivendi

どちらのキャプチャグループも必要な処理を行わないため、正規表現が正しくありません。 1つ目は、セット[a-zA-Z0-9]の単一の文字と、その後に続く<space>:の単一の文字を照合することです。 2番目のキャプチャグループは、0個以上の文字を探しているため常に空ですが、一致の指定も貪欲であってはなりません。つまり、ゼロ文字の一致は有効な結果です。

これらの両方を修正すると、あなたのregex

std::regex rgx("WEBMSG #([a-zA-Z0-9]+) :(.*)");

ただし、単にregexおよびmatch_resultsオブジェクトをインスタンス化しても一致は生成されないため、regexアルゴリズムを適用する必要があります。入力文字列の一部のみを照合する必要があるため、この場合に使用する適切なアルゴリズムは regex_search です。

std::regex_search(s, matches, rgx);

すべてを一緒に入れて

    std::string s{R"(
tХB:[email protected] Connected
tХB:[email protected] WEBMSG #Username :this is a message
tХB:[email protected] Status: visible
)"};

    std::regex rgx("WEBMSG #([a-zA-Z0-9]+) :(.*)");
    std::smatch matches;

    if(std::regex_search(s, matches, rgx)) {
        std::cout << "Match found\n";

        for (size_t i = 0; i < matches.size(); ++i) {
            std::cout << i << ": '" << matches[i].str() << "'\n";
        }
    } else {
        std::cout << "Match not found\n";
    }

ライブデモ

17
Praetorian

"WEBMSG #([a-zA-Z0-9]) :(.*?)":この正規表現は、1文字の長さのユーザー名とセミコロンの後に続くメッセージを含む文字列のみに一致しますが、2番目のグループは常に空になります。 0から無制限。

"WEBMSG #([a-zA-Z0-9]+) :(.*)"が機能するはずです。

2
Mike_Lychkov