C++ 获取两个分隔符字符串之间的字符串

C++ Get String between two delimiter String

本文关键字:字符串 分隔符 之间 两个 获取 C++      更新时间:2023-10-16

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

我的输入如下所示

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

我不知道

当问题清楚地询问如何在两个分隔符字符串而不是一对字符之间获取字符串时,顶部答案是如何获得如此多的选票的

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

情况 1:两个分隔符都是唯一的:

给定要从中提取_0_192.168.1.18_的字符串_STARTDELIMITER_0_192.168.1.18_STOPDELIMITER_,您可以像这样修改顶部答案以获得所需的效果。这是最简单的解决方案,无需引入额外的依赖项(例如 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()),以确保在开始分隔符不在字符串的最开头时,它仍然会正确提取所需的内部字符串,如上面的第二种情况所示。

请参阅演示。

情况 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);
}

相反,如果您想捕获第一个唯一分隔符和最后一个遇到的第二个分隔符之间的任何字符,就像上面提问者评论的那样,请改用find_last_of

情况 3:非唯一第一分隔符,唯一第二分隔符:

与情况 2 非常相似,只需反转第一个分隔符和第二个分隔符之间的逻辑。

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

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

获取 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

希望有帮助

希望你不会介意我用另一个问题来回答:)我会使用 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 拆分时如何避免空令牌?

假设您需要从下面的输出中获取第 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, "");

希望它对其他人有用。

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>