是否有任何内置函数可用两个在C / C ++中的两个分隔符字符串之间获取字符串?
我的输入看起来像
_STARTDELIMITER_0_192.168.1.18_STOPDELIMITER_
我的输出应该是
_0_192.168.1.18_
提前致谢...
答案 0 :(得分:27)
你可以这样做:
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和最后一个终结者之间的文本,尽管它们被重复多次。
答案 1 :(得分:9)
我不知道最佳答案如何获得如此多的选票,当问题清楚地询问如何在两个分隔符字符串之间获取字符串,而不是一对字符<时/强>
如果您愿意这样做,您需要考虑字符串分隔符的长度,因为它不只是一个字符。
如果要从中提取_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_
。
有必要将第二个参数中第一个分隔符的位置添加到std::string::substr
last - (first + start_delim.length())
,以确保在起始分隔符的情况下它仍能正确提取所需的内部字符串并不位于字符串的最开头,如上面第二种情况所示。
请参阅demo。
假设您希望在唯一分隔符和第一个分隔符后遇到的第一个非唯一分隔符之间获取字符串。您可以修改上述函数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);
}
如果你想要捕获第一个唯一分隔符和最后遇到的第二个分隔符之间的任何字符,就像上面提到的那样,请使用find_last_of
代替。
与案例2非常相似,只需反转第一个分隔符和第二个分隔符之间的逻辑。
再次,非常类似于案例2,使容器捕获两个分隔符中的任何一个之间的所有字符串。循环遍历字符串并更新第一个分隔符的位置,使其等于遇到第二个分隔符的位置,并将其间的字符串添加到容器中。重复,直到达到std::string:npos
。
答案 2 :(得分:2)
获取不带空格的2个分隔符字符串之间的字符串。
string str = "STARTDELIMITER_0_192.168.1.18_STOPDELIMITER";
string startDEL = "STARTDELIMITER";
// this is really only needed for the first delimiter
string stopDEL = "STOPDELIMITER";
unsigned firstLim = str.find(startDEL);
unsigned lastLim = str.find(stopDEL);
string strNew = str.substr (firstLim,lastLim);
//This won't exclude the first delimiter because there is no whitespace
strNew = strNew.substr(firstLim + startDEL.size())
// this will start your substring after the delimiter
我尝试组合两个子字符串函数,但它开始打印STOPDELIMITER
希望有所帮助
答案 3 :(得分:1)
希望你不介意我回答另一个问题:) 我会使用boost :: split或boost :: split_iter。 http://www.boost.org/doc/libs/1_54_0/doc/html/string_algo/usage.html#idp166856528
例如代码看到这个问题: How to avoid empty tokens when splitting with boost::iter_split?
答案 4 :(得分:1)
让我们说你需要从下面的输出中获得第五个参数(品牌):
zoneid:zonename:state:zonepath:uuid:brand:ip-type:r/w:file-mac-profile
你不能使用任何&#34; str.find&#34;功能,因为它在中间,但你可以使用&#39; strtok&#39;。 e.g。
char *brand;
brand = strtok( line, ":" );
for (int i=0;i<4;i++) {
brand = strtok( NULL, ":" );
}
答案 5 :(得分:1)
这是一个迟到的答案,但这也可能有用:
string strgOrg= "STARTDELIMITER_0_192.168.1.18_STOPDELIMITER";
string strg= strgOrg;
strg.replace(strg.find("STARTDELIMITER"), 14, "");
strg.replace(strg.find("STOPDELIMITER"), 13, "");
希望它适用于其他人。
答案 6 :(得分:0)
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>