グループマッチングに正規表現を使用しようとしています。 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;
}
一致しません。私の正規表現の何が問題になっていますか?
どちらのキャプチャグループも必要な処理を行わないため、正規表現が正しくありません。 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";
}
"WEBMSG #([a-zA-Z0-9]) :(.*?)"
:この正規表現は、1文字の長さのユーザー名とセミコロンの後に続くメッセージを含む文字列のみに一致しますが、2番目のグループは常に空になります。 0から無制限。
"WEBMSG #([a-zA-Z0-9]+) :(.*)"
が機能するはずです。