我有一个文本文件,其中包含以下文字
许可证=“123456”
GeneralLicense =“56475655”
我想搜索License
以及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;
}
}
由于单词License
也出现在单词GeneralLicense
中,因此行if-statement
中的if (CurrentReadLine.find("License") != std::string::npos)
变为真实两次。
如何指定我想搜索确切的子字符串?
更新:我可以按照某些答案的提法撤消订单,或检查License
是否为索引零。但是没有任何 ROBOUST (旗帜或其他东西)我们可以精确地寻找完全匹配( 像我们在大多数编辑器中那样的东西,例如MS Word等。 )。
答案 0 :(得分:6)
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;
}
}
答案 1 :(得分:1)
更强大的搜索称为正则表达式:
#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;
}
}
\ b转义序列表示单词边界。
。*表示&#34;任何字符序列,包括零字符&#34;
编辑:您也可以使用regex_search而不是regex_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;
}
}
这与您的代码更匹配,但请注意,如果在等号后面也找到关键字,它会被绊倒。如果您想要最大的稳健性,请使用regex_match并准确指定整行应匹配的内容。
答案 2 :(得分:0)
您可以检查子字符串出现的位置是否为索引零,或者初始位置前面的字符是否为空格:
bool findAtWordBoundary(const std::string& line, const std::string& search) {
size_t pos = line.find(search);
return (pos != std::string::npos) && (pos== 0 || isspace(line[pos-1]));
}
我们可以指定哪些东西(旗帜或其他东西)来寻找完全匹配?
在某种程度上,find
已经找到完全匹配。但是,它将字符串视为表示单个字符的无意义数字序列。这就是为什么std::string
类缺少&#34;完整单词&#34;的概念,它存在于库的其他部分,例如正则表达式。
答案 3 :(得分:0)
您可以编写一个首先测试最大匹配的函数,然后返回您想要的匹配信息。
有点像:
// find the largest matching element from the set and return it
std::string find_one_of(std::set<std::string, std::greater<std::string>> const& tests, std::string const& s)
{
for(auto const& test: tests)
if(s.find(test) != std::string::npos)
return test;
return {};
}
int main()
{
std::string text = "abcdef";
auto found = find_one_of({"a", "abc", "ab"}, text);
std::cout << "found: " << found << '\n'; // prints "abc"
}
答案 4 :(得分:0)
如果所有匹配都在pos 0开始,而none是另一个的前缀,则以下内容可能有效
if (CurrentReadLine.substr( 0, 7 ) == "License")
答案 5 :(得分:0)
您可以tokenize字符串并与搜索键和令牌进行完整比较
示例:
#include <string>
#include <sstream>
#include <vector>
#include <iostream>
auto tokenizer(const std::string& line)
{
std::vector<std::string> results;
std::istringstream ss(line);
std::string s;
while(std::getline(ss, s, ' '))
results.push_back(s);
return results;
}
auto compare(const std::vector<std::string>& tokens, const std::string& key)
{
for (auto&& i : tokens)
if ( i == key )
return true;
return false;
}
int main()
{
std::string x = "License = \"12345\"";
auto token = tokenizer(x);
std::cout << compare(token, "License") << std::endl;
std::cout << compare(token, "GeneralLicense") << std::endl;
}