在字符串中搜索通配符年份C ++

时间:2015-04-14 18:19:33

标签: c++ find wildcard

我循环浏览文本文件,将每个段落读成字符串。我想处理包含一年的任何段落,但如果没有找到年份,那么我想继续循环遍历该文件。当找到一年时,我想知道找到那一年的指数。

为了简单起见,我试图避免任何提升或正则表达式代码。我还假设,为了简单起见,唯一感兴趣的年份将是在20世纪和2000年代。我尝试了以下代码,但由于某种原因,通配符不起作用。是因为通配符对数字不起作用吗?

string sParagraph = "Aramal et al. (2011), Title";
int iIndex;

if (sParagraph.find("19??")!=string::npos)
    iIndex = sParagraph.find("19??");
else if (sParagraph.find("20??")!=string::npos)
    iIndex = sParagraph.find("20??");
else
    continue;

3 个答案:

答案 0 :(得分:0)

编辑:我刚刚重读了这个问题并注意到这个答案可能太无关紧要了。对不起,如果是。

我几天前正在寻找类似的东西。我的方法可能非常(非常非常)效率低下:我循环遍历整个字符串并使用' atoi()'看看每组四个角色是否都是一年。

for (int i = 0; i < txt.length() - 3; i++)
{
    string t = txt.substr(i, 4); //Take a group of four characters.

    int year = atoi((char*)t.c_str());

    if (year > 1800 && year < 3000)
    {
        break;
    }
    else year = 0;
}

最后,&#39;年&#39;是零或实际年份。

答案 1 :(得分:0)

如果不使用正则表达式或增强代码,可能会使代码更具可读性,但它不会更简单。

“简单”一遍伪算法:

map<int, std::vector<int>> years;
String par = " ... "

//inefficient but didn't want to have to add more complicated code
//in the while loop. Just want to solution to be clear
int par_index = par.find_first_of("19"); 
if(par_index == string::npos) 
    par_index = par.find_first_of("20");
if(par_index == string::npos)
    //skip //No years in this paragraph

while(par_index < par.size()) {
    string year(par, par_index, 4);
    int year = atoi(year.c_str());  //or use C++11 stoi
    if(2100 < year && year >= 1900)
        years.at(year).push_back(par_index);
    par_index += 4;
}

这将创建一个映射,其中键是年份,值是一个int的向量,表示年份登陆的索引。

答案 2 :(得分:0)

所以你当然可以这样做。但它不会更简单,它会更复杂。

无论如何,这可能是您最好的非正则表达式解决方案。它使用string::iterator而不是位置:

string sParagraph = "Aramal et al. (2011), Title";
auto iIndex = adjacent_find(sParagraph.begin(), sParagraph.end(), [](char i, char j){return i == '1' && j == '9' || i == '2' && j == '0'; });
const auto end = next(sParagraph.end(), -3);

while (iIndex < end && (isdigit(static_cast<int>(*next(iIndex, 2))) == false || isdigit(static_cast<int>(*next(iIndex, 3))) == false)){
    iIndex = adjacent_find(next(iIndex, 4), sParagraph.end(), [](char i, char j){return i == '1' && j == '9' || i == '2' && j == '0'; });
}

要使用此功能,您需要检查是否已迭代到end

if(iIndex < end){
    continue;
}

为了便于比较,您可以使用regex_search来确定年份是否存在:

string sParagraph = "Aramal et al. (2011), Title";
smatch iIndex;

if (!regex_search(sParagraph, iIndex, regex("(?:19|20)\\d{2}"))){
    continue;
}

smatch包含更多信息,只包含一个位置,但如果您想要年初的索引,您可以执行以下操作:iIndex.position()

对于不熟悉C ++ 11功能的人来说,常见的陷阱是:“我不明白如何使用这些东西,它必须比我已经知道的更复杂。”然后回到他们已经知道的东西。不要犯这个错误,请使用regex_search