在字符串中查找确切的子str
Find an exact substr in a string
>我有一个包含以下文本的文本文件
许可证 ="123456">
通用许可证 ="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
是否在索引零处。但是,我们是否可以寻找确切的匹配项(类似于我们在大多数编辑器中拥有的东西,例如MS Word等(。
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;
}
}
更健壮的搜索称为正则表达式:
#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 转义序列表示单词边界。
.* 表示"任何字符序列,包括零个字符">
编辑:您也可以使用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并准确指定整条生产线应匹配的内容。
您可以检查子字符串出现的位置是否位于索引零处,或者初始位置前面的字符是否为空格:
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
类缺少"全词"的概念,该概念存在于库的其他部分,例如正则表达式。
您可以编写一个函数,该函数首先测试最大的匹配项,然后返回您想要的有关匹配项的任何信息。
有点像:
// 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"
}
如果所有匹配项都以 pos 0 开头,并且没有一个是另一个的前缀,则以下内容可能有效
if (CurrentReadLine.substr( 0, 7 ) == "License")
您可以标记字符串,并使用搜索关键字和标记进行全面比较
例:
#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;
}
- 字符串变量,比如说"字符串str",可以直接复制到数组中吗?
- std::smatch str() 未返回正确的字符串
- 使用 str.erase() 的索引擦除字符串的元素?
- 在字符串中查找确切的子str
- 在 ss.clear() 之后使用 ss.str( " ") 用于新定义的字符串流
- .Net字符串是否可以在不复制的情况下交给fn(const char16_t*str)
- 从"char"到"const char*"的转换无效 [-fpermissive] str::atoi (字符串到整数)
- 字符串流.str().cstr()有问题吗
- 字符串中的 cin>>str+1 是什么C++?
- 我是否负责释放/删除stringstream.str()返回的字符串
- 流的内容和返回的字符串“str()”之间的差异
- 字符 *str;str= "HELLO" ;如何在不为字符串分配任何内存的情况下工作?
- 使用 str.at(x) 将字符串转换为 int
- 将字符串转换为无符号字符 str
- 在字符串 c++(无子字符串)上使用 str.find() 时执行操作
- 为什么当我们反转此函数中的字符串时,char *str 的指针没有改变?
- 使用 c.str 从字符串转换为 cstring
- 有没有使用 str.substr( ) 在给定位置提取子字符串的替代方法
- 使用str()和rdbuf()打印字符串流
- 转换str字符串以用于std::getline分隔符的字符串