正在检查字符串中是否有匹配的子字符串

Checking a string for matching substrings

本文关键字:字符串 是否 检查      更新时间:2023-10-16

我有一个很长的段序列,用分隔符(比如'-')分隔。它的形式是:

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。但是它们是不同的书A、B。因此,我返回false

我曾尝试使用std::regex来完成此操作。

对于用户未输入的所有索引,我用
填充临时字符串的这些部分([^-]+)-,即一个或多个字符的字符串,不包含-

对于用户输入的两个索引,我面临一个问题。如果我使用捕获组,并在第一个索引中指定([^-]+-),并在第二个索引中使用\1(或任何第n个捕获组),则结果不一致BookANewBook匹配,这不是预期的。在某些情况下,a-not-匹配。

然后我用这个临时字符串匹配上面的句子。

如何检查从开始到结束的字符以及给定索引处子字符串的长度是否相等

此外,我发现这个问题很相似,但有些结果并不一致。构造正则表达式

PS:考虑到做正则表达式很容易,而不是提取字符串给定索引处的段并进行比较,我更喜欢前者。字符串的数目可能达到数百。

感谢更好的解决方案。

一个可能的解决方案(当然不是唯一的解决方案)可以是只使用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;
}

示例

由于这是(正如我所理解的)"在第n个分隔符处查找子字符串"的问题,我不会选择regex,而将其留给更复杂的模式匹配任务。

我同意Marco A.正则表达式对这项工作来说太过分了。使用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:
 */