Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Get String between two delimiter String

Tags:

c++

c

Is there any inbuilt function available two get string between two delimiter string in 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...

like image 554
Haris Avatar asked Sep 14 '13 10:09

Haris


People also ask

How do I extract text between two delimiters?

The easiest way to extract a substring between two delimiters is to use the text to column feature in Excel, especially if you have multiple delimiters. In this example, use =MID(A2, SEARCH(“-“,A2) + 1, SEARCH(“-“,A2,SEARCH(“-“,A2)+1) – SEARCH(“-“,A2) – 1) in cell B2 and drag it to the entire data range.

How do you find the string between two characters?

To extract part string between two different characters, you can do as this: Select a cell which you will place the result, type this formula =MID(LEFT(A1,FIND(">",A1)-1),FIND("<",A1)+1,LEN(A1)), and press Enter key. Note: A1 is the text cell, > and < are the two characters you want to extract string between.

How to split up a string in C?

In C, the strtok() function is used to split a string into a series of tokens based on a particular delimiter. A token is a substring extracted from the original string.

How to split a string by space in C?

To split a string we need delimiters - delimiters are characters which will be used to split the string. Suppose, we've the following string and we want to extract the individual words. char str[] = "strtok needs to be called several times to split a string"; The words are separated by space.


4 Answers

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 STOPDELIMITER delimiter will occur only once at the end.

EDIT:

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

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.

like image 91
Saksham Avatar answered Oct 13 '22 07:10

Saksham


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:

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

#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.

It is necessary to add the position of the first delimiter in the second argument to std::string::substr as 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.

See the demo.

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

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_str to use find_first_of instead to get the desired effect:

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_of instead.

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

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

Case 4: Both delimiters are not unique:

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:npos is reached.

like image 22
ifma Avatar answered Oct 13 '22 09:10

ifma


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

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

Hope that helps

like image 31
kullen Avatar answered Oct 13 '22 08:10

kullen


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

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

like image 37
Jan Korous Avatar answered Oct 13 '22 09:10

Jan Korous