Kut KV
Kut KV

Reputation: 15

Checking a string for matching substrings

I have a long sequence of segments separated by a delimiter say '-'. It is of the form:

I-am-logged-into-StackOverFlow-I-am-using-StackOverFlow-
I-am-reading-a-book-A-I-have-written-a-book-B-

The user specifies the segments that I have to compare.

Say, for string - 1, above: He inputs 5 and 9. Both contain StackOverFlow, so I return true.

For string - 2, segments 6, 12. But. they are different books A,B. So, I return false.

I have tried to do this using std::regex.

For all indices not entered by the user, I fill in those portions of a temporary string with
([^-]+)-, i.e. a string of one or more characters not containing a -, but ending with that.

For the two indices the user inputs,I face a problem. If I go with capturing groups and specify ([^-]+-) in the first index and use a \1 (or any nth capturing group) for the second index, the results are inconsistent. Book matches ANewBook which is not what is expected. In some cases, a- matches with not-.

Then I match the sentences above, with this temp string.

How do I check for equality - the characters from start to end, and the length of the substrings at the given indices?

Also, I find this question similar, but some of the results there are not consistent. Constructing a regular expression

PS: Considering the fact that it is easy to do a regex rather than extracting the segments at the given indices of a string and comparing the same, I would prefer the former. The number of string may run into hundreds.

Better solutions appreciated.

Upvotes: 1

Views: 266

Answers (2)

Tobias
Tobias

Reputation: 5198

I agree with Marco A. Regular expressions are overkill for this job. A running variant with istringstream:

#include<iostream>
#include<string>
#include<sstream>
#include<limits>

bool equalSubStr(const std::string& str, int i1, int i2, char sep) {
    std::istringstream ss(str);
    std::string sub1, sub2;
    int i=1;
    if( i1 > i2 )
        std::swap(i1,i2);

    auto advance = [&ss,sep](int &i, int iLim) {
        for(; i!=iLim; i++) {
            if(!ss.ignore(std::numeric_limits<std::streamsize>::max(),sep))
                return false;
        }
        return true;
    };

    if( ( advance(i,i1)
            && std::getline(ss,sub1,sep)
            && advance(++i,i2)
            && std::getline(ss,sub2,sep) ) )
        return sub1 == sub2;

    return false;
}

int main()
{
    std::string str1="I-am-logged-into-StackOverFlow-I-am-using-StackOverFlow-";

    int i1=5;
    int i2=9;

    if( equalSubStr(str1,5,9,'-') )
        std::cout << "\nSubstrings 5 and 9 are equal.";
    if( equalSubStr(str1,1,6,'-') )
        std::cout << "\nSubstrings 1 and 6 are equal.";
    if( !equalSubStr(str1,2,3,'-') )
        std::cout << "\nSubstrings 2 and 3 are not equal.";

    return 0;
}

/*
    Local Variables:
    compile-command: "g++ --std=c++11 test.cc -o ./test.exe && ./test.exe"
    End:
 */

Upvotes: 0

Marco A.
Marco A.

Reputation: 43662

A possible solution (surely not the only one) could be to just use std::find and extract two substrings for comparison

(warning: the following code hasn't been extensively tested and might contain errors, it is intended as a concept idea for further refinement to suit your needs)

bool match_positions(const std::string& str, int p1, int p2) {
    int wordNo = 1;
    size_t beg = 0, pos;
    std::string first, second;
    while ((pos = str.find('-', beg)) != std::string::npos ||
        (first.empty() && second.empty()) ) {
        if (wordNo == p1)
            first = str.substr(beg, pos - beg);
        if (wordNo == p2)
            second = str.substr(beg, pos - beg);
        beg = pos + 1;
        ++wordNo;
    }
    if (first.empty() || second.empty())
        return false;
    else
        if (!first.compare(second))
            return true;
        else
            return false;
}

Example

Since this is (as I understood it) a "find-the-substring-at-nth-delimiter" problem, I wouldn't go for regex and leave those for more complex pattern matching tasks.

Upvotes: 1

Related Questions