Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find an exact substr in a string

Tags:

c++

I have a text file which contains the following text

License = "123456"

GeneralLicense = "56475655"

I want to search for License as well as for GeneralLicense.

while (getline(FileStream, CurrentReadLine))
{

    if (CurrentReadLine.find("License") != std::string::npos)
    {
        std::cout << "License Line: " << CurrentReadLine;
    }
    if (CurrentReadLine.find("GeneralLicense") != std::string::npos)
    {
        std::cout << "General License Line: " << CurrentReadLine;
    }
}

Since the word License also present in the word GeneralLicense so if-statement in the line if (CurrentReadLine.find("License") != std::string::npos) becomes true two times.

How can I specify that I want to search for the exact sub-string?

UPDATE: I can reverse the order as mentioned by some Answers OR check if the License is at Index zero. But isn't there anything ROBOUST (flag or something) which we can speficy to look for the exact match (Something like we have in most of the editors e.g. MS Word etc.).

like image 289
skm Avatar asked May 19 '17 15:05

skm


2 Answers

while (getline(FileStream, CurrentReadLine))
{
    if (CurrentReadLine.find("GeneralLicense") != std::string::npos)
    {
        std::cout << "General License Line: " << CurrentReadLine;
    }
    else if (CurrentReadLine.find("License") != std::string::npos)
    {
        std::cout << "License Line: " << CurrentReadLine;
    }
}
like image 149
Jeffrey Chung Avatar answered Sep 22 '22 07:09

Jeffrey Chung


The more ROBUST search is called a regex:

#include <regex>

while (getline(FileStream, CurrentReadLine))
{
    if(std::regex_match(CurrentReadLine,
        std::regex(".*\\bLicense\\b.*=.*")))
    {
        std::cout << "License Line: " << CurrentReadLine << std::endl;
    }
    if(std::regex_match(CurrentReadLine,
        std::regex(".*\\bGeneralLicense\\b.*=.*")))
    {
        std::cout << "General License Line: " << CurrentReadLine << std::endl;
    }
}

The \b escape sequences denote word boundaries.

.* means "any sequence of characters, including zero characters"

EDIT: You could also use regex_search instead of regex_match to search for substrings that match instead of using .* to cover the parts that don't match:

#include <regex>

while (getline(FileStream, CurrentReadLine))
{
    if(std::regex_search(CurrentReadLine, std::regex("\\bLicense\\b"))) 
    {
        std::cout << "License Line: " << CurrentReadLine << std::endl;
    }
    if(std::regex_search(CurrentReadLine, std::regex("\\bGeneralLicense\\b")))
    {
        std::cout << "General License Line: " << CurrentReadLine << std::endl;
    }
}

This more closely matches your code, but note that it will get tripped up if the keywords are also found after the equals sign. If you want maximum robustness, use regex_match and specify exactly what the whole line should match.

like image 41
L. Scott Johnson Avatar answered Sep 24 '22 07:09

L. Scott Johnson