17

在 C/C++ 中的两个分隔符字符串之间是否有任何可用的内置函数两个 get 字符串?

我的输入看起来像

_STARTDELIMITER_0_192.168.1.18_STOPDELIMITER_

我的输出应该是

_0_192.168.1.18_

提前致谢...

4

7 回答 7

35

你可以这样做:

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 之间发送文本,尽管它们被重复多次。

于 2013-09-14T10:38:15.300 回答
13

我不知道当问题清楚地询问如何在两个分隔符字符串之间获取字符串而不是一对字符时,最佳答案如何获得如此选票

如果您想这样做,您需要考虑字符串分隔符的长度,因为它不仅仅是一个字符。

情况 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_两次。

有必要将第二个参数中第一个定界符的位置添加到std::string::substraslast - (first + start_delim.length())以确保在起始定界符不位于字符串的最开头的情况下它仍能正确提取所需的内部字符串,如所示在上面的第二种情况下。

请参阅演示

案例2:唯一的第一个分隔符,非唯一的第二个分隔符:

假设您想在唯一分隔符和第一个分隔符之后遇到的第一个非唯一分隔符之间获取一个字符串。您可以修改上面的函数get_str_between_two_strfind_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改用。

案例3:非唯一的第一个分隔符,唯一的第二个分隔符:

与案例2非常相似,只是将第一个分隔符和第二个分隔符之间的逻辑颠倒过来。

情况 4:两个分隔符都不唯一:

同样,与案例 2 非常相似,创建一个容器来捕获两个分隔符之间的所有字符串。循环遍历字符串并将第一个定界符的位置更新为遇到第二个定界符时的位置,并将中间的字符串添加到容器中。重复直到std::string:npos达到。

于 2017-03-24T14:59:58.487 回答
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

希望有帮助

于 2014-09-04T01:55:23.697 回答
1

希望你不会介意我回答另一个问题 :) 我会使用 boost::split 或 boost::split_iter。 http://www.boost.org/doc/libs/1_54_0/doc/html/string_algo/usage.html#idp166856528

例如代码看到这个SO问题: How to Avoid empty tokens when split with boost::iter_split?

于 2013-09-14T11:47:15.717 回答
1

假设您需要从下面的输出中获取第 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, ":" );
}
于 2015-03-09T17:32:11.457 回答
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, "");

希望它适用于其他人。

于 2015-04-25T06:51:45.770 回答
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> 
于 2016-10-12T22:15:04.030 回答