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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18800796/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 22:13:18  来源:igfitidea点击:

C++ Get String between two delimiter String

c++c

提问by Haris

Is there any inbuilt function available two get string between two delimiter string in C/C++?

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

My input look like

我的输入看起来像

_STARTDELIMITER_0_192.168.1.18_STOPDELIMITER_

And my output should be

我的输出应该是

_0_192.168.1.18_

Thanks in advance...

提前致谢...

回答by Saksham

You can do as:

你可以这样做:

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);

Considering your STOPDELIMITERdelimiter will occur only once at the end.

考虑到您的STOPDELIMITER分隔符在最后只会出现一次。

EDIT:

编辑:

As delimiter can occur multiple times, change your statement for finding STOPDELIMITER to:

由于分隔符可以多次出现,请将用于查找 STOPDELIMITER 的语句更改为:

unsigned last = str.find_last_of(STOPDELIMITER);

This will get you text between the first STARTDELIMITER and LAST STOPDELIMITER despite of them being repeated multiple times.

这将使您在第一个 STARTDELIMITER 和 LAST STOPDELIMITER 之间获得文本,尽管它们被重复多次。

回答by ifma

I have no idea how the top answer received so many votes that it did when the question clearly asks how to get a string between two delimiter strings, and not a pair of characters.

我不知道上面的答案如何获得如此多的选票,它没有在这个问题显然问如何获得线二分隔符之间的字符串,而不是对字符

If you would like to do so you need to account for the length of the string delimiter, since it will not be just a single character.

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

Case 1: Both delimiters are unique:

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

Given a string _STARTDELIMITER_0_192.168.1.18_STOPDELIMITER_that you want to extract _0_192.168.1.18_from, you could modify the top answer like so to get the desired effect. This is the simplest solution without introducing extra dependencies (e.g Boost):

给定要从_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;
}

Will print _0_192.168.1.18_twice.

会打印_0_192.168.1.18_两次。

It is necessary to add the position of the first delimiter in the second argument to std::string::substras last - (first + start_delim.length())to ensure that the it would still extract the desired inner string correctly in the event that the start delimiter is not located at the very beginning of the string, as demonstrated in the second case above.

有必要添加第一个分隔符的位置在第二个参数std::string::substr作为last - (first + start_delim.length()),以确保它仍然会正确地提取所需的内部串中的起始分隔符不位于最开始的字符串,如证实事件在上面的第二种情况下。

See the demo.

请参阅演示

Case 2: Unique first delimiter, non-unique second delimiter:

情况 2:唯一的第一个分隔符,非唯一的第二个分隔符:

Say you want to get a string between a unique delimiter and the first non unique delimiter encountered after the first delimiter. You could modify the above function get_str_between_two_strto use find_first_ofinstead to get the desired effect:

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

If instead you want to capture any characters in between the first unique delimiter and the last encountered second delimiter, like what the asker commented above, use find_last_ofinstead.

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

Case 3: Non-unique first delimiter, unique second delimiter:

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

Very similar to case 2, just reverse the logic between the first delimiter and second delimiter.

与情况2非常相似,只是将第一个定界符和第二个定界符之间的逻辑颠倒了。

Case 4: Both delimiters are not unique:

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

Again, very similar to case 2, make a container to capture all strings between any of the two delimiters. Loop through the string and update the first delimiter's position to be equal to the second delimiter's position when it is encountered and add the string in between to the container. Repeat until std::string:nposis reached.

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

回答by kullen

To get a string between 2 delimiter strings without white spaces.

获取没有空格的 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

I tried combining the two substring functions but it started printing the STOPDELIMITER

我尝试组合两个子字符串函数,但它开始打印 STOPDELIMITER

Hope that helps

希望有帮助

回答by Dalibor

Let's say you need to get 5th argument (brand) from output below:

假设您需要从下面的输出中获得第 5 个参数(品牌):

zoneid:zonename:state:zonepath:uuid:brand:ip-type:r/w:file-mac-profile

You cannot use any "str.find" function, because it is in the middle, but you can use 'strtok'. e.g.

你不能使用任何“str.find”函数,因为它在中间,但你可以使用“strtok”。例如

char *brand;
brand = strtok( line, ":" );
for (int i=0;i<4;i++) {
    brand = strtok( NULL, ":" );
}

回答by Falcon

This is a late answer, but this might work too:

这是一个迟到的答案,但这也可能有效:

string strgOrg= "STARTDELIMITER_0_192.168.1.18_STOPDELIMITER";
string strg= strgOrg;

strg.replace(strg.find("STARTDELIMITER"), 14, "");
strg.replace(strg.find("STOPDELIMITER"), 13, "");

Hope it works for others.

希望它对其他人有用。

回答by Jan Korous

Hope you won't mind I'm answering by another question :) I would use boost::split or boost::split_iter. http://www.boost.org/doc/libs/1_54_0/doc/html/string_algo/usage.html#idp166856528

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

For example code see this SO question: How to avoid empty tokens when splitting with boost::iter_split?

例如代码见这个问题: How to avoid empty tokens when splitting with boost::iter_split?

回答by telcom

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"; }

or if you are using Windows and have access to c++14, the following,

或者,如果您使用的是 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;
    }
}

Example:

例子:

   string strout;
    getBtwString("it's_12345bb2","it's","bb2",strout); 
    getBtwString("it's_12345bb2"s,"it's"s,"bb2"s,strout); // second solution

Headers:

标题:

#include <regex> // second solution
#include <string.h>