C/C++ で 2 つの区切り文字列の間にある 2 つの get string を利用できる組み込み関数はありますか?
私の入力は次のようになります
_STARTDELIMITER_0_192.168.1.18_STOPDELIMITER_
そして私の出力は
_0_192.168.1.18_
前もって感謝します...
次のようにできます。
string str = "STARTDELIMITER_0_192.168.1.18_STOPDELIMITER";
unsigned first = str.find(STARTDELIMITER);
unsigned last = str.find(STOPDELIMITER);
string strNew = str.substr (first,last-first);
STOPDELIMITER
区切り文字が最後に一度だけ発生することを考慮してください。
編集:
区切り文字は複数回発生する可能性があるため、STOPDELIMITER を見つけるためのステートメントを次のように変更します。
unsigned last = str.find_last_of(STOPDELIMITER);
これにより、複数回繰り返されているにもかかわらず、最初の STARTDELIMITER と LAST STOPDELIMITER の間にテキストが表示されます。
質問が文字のペアではなく、 2つの区切り文字列の間の文字列を取得する方法を明確に尋ねたときに、どのようにしてトップの回答が非常に多くの票を獲得したのか、私にはわかりません。
そのようにしたい場合は、文字列の区切り文字の長さを考慮する必要があります。これは、1 文字だけではないためです。
_STARTDELIMITER_0_192.168.1.18_STOPDELIMITER_
抽出したい文字列を_0_192.168.1.18_
指定すると、上位の回答をそのように変更して、目的の効果を得ることができます。これは、追加の依存関係 (Boost など) を導入しない最も単純なソリューションです。
#include <iostream>
#include <string>
std::string get_str_between_two_str(const std::string &s,
const std::string &start_delim,
const std::string &stop_delim)
{
unsigned first_delim_pos = s.find(start_delim);
unsigned end_pos_of_first_delim = first_delim_pos + start_delim.length();
unsigned last_delim_pos = s.find(stop_delim);
return s.substr(end_pos_of_first_delim,
last_delim_pos - end_pos_of_first_delim);
}
int main() {
// Want to extract _0_192.168.1.18_
std::string s = "_STARTDELIMITER_0_192.168.1.18_STOPDELIMITER_";
std::string s2 = "ABC123_STARTDELIMITER_0_192.168.1.18_STOPDELIMITER_XYZ345";
std::string start_delim = "_STARTDELIMITER";
std::string stop_delim = "STOPDELIMITER_";
std::cout << get_str_between_two_str(s, start_delim, stop_delim) << std::endl;
std::cout << get_str_between_two_str(s2, start_delim, stop_delim) << std::endl;
return 0;
}
_0_192.168.1.18_
2回印刷します。
std::string::substr
示されているように、開始区切り文字が文字列の最初に配置されlast - (first + start_delim.length())
ていない場合でも、目的の内部文字列を正しく抽出できるように、2 番目の引数に最初の区切り文字の位置を追加する必要があります。上記の 2 番目の場合。
デモを参照してください。
一意の区切り記号と、最初の区切り記号の後に検出された最初の一意でない区切り記号の間の文字列を取得したいとします。上記の関数を変更して、目的の効果を得るために代わりにget_str_between_two_str
使用できます。find_first_of
std::string get_str_between_two_str(const std::string &s,
const std::string &start_delim,
const std::string &stop_delim)
{
unsigned first_delim_pos = s.find(start_delim);
unsigned end_pos_of_first_delim = first_delim_pos + start_delim.length();
unsigned last_delim_pos = s.find_first_of(stop_delim, end_pos_of_first_delim);
return s.substr(end_pos_of_first_delim,
last_delim_pos - end_pos_of_first_delim);
}
代わりに、質問者が上記でコメントしたように、最初の一意の区切り文字と最後に検出された 2 番目の区切り文字の間の任意の文字をキャプチャする場合は、find_last_of
代わりに使用します。
ケース 2 と非常によく似ていますが、最初の区切り文字と 2 番目の区切り文字の間のロジックを逆にするだけです。
ここでも、ケース 2 と非常によく似ており、2 つの区切り文字の間にあるすべての文字列をキャプチャするコンテナーを作成します。文字列をループし、最初の区切り文字の位置が検出されたときに 2 番目の区切り文字の位置と等しくなるように更新し、その間に文字列をコンテナーに追加します。に達するまで繰り返しstd::string:npos
ます。
以下の出力から 5 番目の引数 (ブランド) を取得する必要があるとします。
zoneid:zonename:state:zonepath:uuid:brand:ip-type:r/w:file-mac-profile
「str.find」関数は真ん中なので使えませんが、「strtok」は使えます。例えば
char *brand;
brand = strtok( line, ":" );
for (int i=0;i<4;i++) {
brand = strtok( NULL, ":" );
}
これは遅い答えですが、これもうまくいくかもしれません:
string strgOrg= "STARTDELIMITER_0_192.168.1.18_STOPDELIMITER";
string strg= strgOrg;
strg.replace(strg.find("STARTDELIMITER"), 14, "");
strg.replace(strg.find("STOPDELIMITER"), 13, "");
それが他の人のために働くことを願っています。
私が別の質問で答えていることを気にしないでください:)私はboost::splitまたはboost::split_iterを使用します。 http://www.boost.org/doc/libs/1_54_0/doc/html/string_algo/usage.html#idp166856528
コードの例については、この SO の質問を参照してください: Boost::iter_split で分割するときに空のトークンを回避する方法は?
void getBtwString(std::string oStr, std::string sStr1, std::string sStr2, std::string &rStr)
{
int start = oStr.find(sStr1);
if (start >= 0)
{
string tstr = oStr.substr(start + sStr1.length());
int stop = tstr.find(sStr2);
if (stop >1)
rStr = oStr.substr(start + sStr1.length(), stop);
else
rStr ="error";
}
else
rStr = "error"; }
または、Windows を使用していて、c++14 にアクセスできる場合は、次のようにします。
void getBtwString(std::string oStr, std::string sStr1, std::string sStr2, std::string &rStr)
{
using namespace std::literals::string_literals;
auto start = sStr1;
auto end = sStr2;
std::regex base_regex(start + "(.*)" + end);
auto example = oStr;
std::smatch base_match;
std::string matched;
if (std::regex_search(example, base_match, base_regex)) {
if (base_match.size() == 2) {
matched = base_match[1].str();
}
rStr = matched;
}
}
例:
string strout;
getBtwString("it's_12345bb2","it's","bb2",strout);
getBtwString("it's_12345bb2"s,"it's"s,"bb2"s,strout); // second solution
ヘッダー:
#include <regex> // second solution
#include <string.h>