Проверка строки на соответствие подстрок

У меня есть длинная последовательность сегментов, разделенных разделителем, скажем "-". Это имеет форму:

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

Пользователь указывает сегменты, которые я должен сравнить.

Скажем, для строки - 1, выше: он вводит 5 и 9. Оба содержат StackOverFlow, поэтому я возвращаю true.

Для строки - 2, сегменты 6, 12. Но. это разные книги А, Б. Итак, я вернул false.

Я пытался сделать это с помощью std:: regex.

Для всех индексов, не введенных пользователем, я заполняю эти части временной строки с помощью
([^ -] +) -, то есть строка из одного или нескольких символов, не содержащая -, но заканчивающаяся этим.

Для двух индексов пользовательских входов я сталкиваюсь с проблемой. Если я пойду с группами захвата и укажу ([^-]+-) в первом индексе и использую \ 1 (или любую n-ую группу захвата) для второго индекса, результаты будут противоречивыми. Книга соответствует ANewBook, что не то, что ожидается. В некоторых случаях a- соответствует not-.

Затем я сопоставляю приведенные выше предложения с этой временной строкой.

Как проверить на равенство - символы от начала до конца и длину подстрок при заданных индексах?

Кроме того, я нахожу этот вопрос похожим, но некоторые результаты там не соответствуют. Построение регулярного выражения

PS: Учитывая тот факт, что легко сделать регулярное выражение, а не извлекать сегменты по заданным индексам строки и сравнивать их, я бы предпочел первое. Количество строк может исчисляться сотнями.

Лучшие решения приветствуются.

2 ответа

Решение

Возможное решение (конечно, не единственное) может состоять в том, чтобы просто использовать std::find и извлечь две подстроки для сравнения

(предупреждение: следующий код не был тщательно протестирован и может содержать ошибки, он предназначен в качестве концепции для дальнейшего уточнения в соответствии с вашими потребностями)

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

пример

Поскольку это (как я понял) проблема "найти подстроку-на-н-делитере", я бы не стал использовать регулярные выражения и оставить их для более сложных задач сопоставления с образцом.

Я согласен с Марко А. Регулярные выражения для этой работы излишни. Бегущий вариант с 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:
 */
Другие вопросы по тегам