在c++字符串中查找精确的单词匹配



我有以下字符串:

std::string s1 = "IAmLookingForAwordU and I am the rest of the phrase";
std::string keyWord = "IAmLookingForAword";

我想知道关键字是否在s1

中完全匹配我使用:

if ( s1.find(keyWord) != std::string::npos )
{
std::cout << "Found " << keyWord << std::endl;
}

,但是find函数捕获IAmLookingForAwordU中的IAmLookingForAword,并且if语句设置为true。但是,我只想捕获我正在寻找的keyWork的精确匹配。

有什么方法可以用c++字符串做到这一点吗?

如果您想继续使用std::string::find,您可以测试单词前后的字符是否超出了字符串,标点符号或空格的范围:

bool find_word(const std::string& haystack,const std::string& needle){
auto index = haystack.find(needle);
if (index == std::string::npos) return false;
auto not_part_of_word = [&](int index){ 
if (index < 0 || index >= haystack.size()) return true;
if (std::isspace(haystack[index]) || std::ispunct(haystack[index])) return true;
return false;
};
return not_part_of_word(index-1) && not_part_of_word(index+needle.size());
}

int main()
{
std::cout << find_word("test","test") << "n";    // 1
std::cout << find_word(" test ","test") << "n";  // 1
std::cout << find_word("AtestA","test") << "n";  // 0
std::cout << find_word("testA","test") << "n";   // 0
std::cout << find_word("Atest","test") << "n";   // 0
}

一个想法是使用正则表达式。这里有一个简单的例子。正则表达式在单词"exact"的两边使用b。在正则表达式中,b表示它应该只匹配单词边界(例如空格或标点符号)。这个正则表达式将只匹配单词"exact"而不是"确切"这个词。注意:在正则表达式中使用原始字符串通常更容易,因为反斜杠字符对c++字符串和正则表达式都有特殊的含义。

#include <string>
#include <regex>
#include <iostream>
int main() {
std::regex re(R"(bexactb)");
std::smatch m;
std::string string1 = "Does this match exactly?";
std::string string2 = "Does this match with exact precision?";
if (std::regex_search(string1, m, re))
{
// this shouldn't print
std::cout << "It matches string1" << std::endl;
}
if (std::regex_search(string2, m, re))
{
// this should print
std::cout << "It matches string2" << std::endl;
}
return 0;
}

如果你正在搜索的单词是可变的(即你正在寻找的单词每次都是不同的),那么使用正则表达式就变得复杂得多,因为你必须确保你正确地验证输入,以及在正则表达式中正确地转义具有特殊含义的字符。因此,我可能会选择其他解决方案。

find函数捕获IAmLookingForAwordU中的IAmLookingForAword,并且if语句设置为true。但是,我只想捕获我正在寻找的keyWork的精确匹配。

有什么方法可以用c++字符串做到这一点吗?

你可以定义一个辅助函数:

#include <string>
#include <cctype>
// ...
bool has_word(std::string const& s, std::string const& key_word) {
auto const found_at = s.find(key_word);
return found_at != std::string::npos
&& (!found_at || (found_at && !isalpha(s[found_at - 1])))
&& found_at <= s.size() - key_word.size() && !isalpha(s[found_at + key_word.size()]);
}

然后像这样使用:

if (has_word(s1, keyWord))
std::cout << "Found " << keyWord << std::endl;

将输入字符串标记化,然后比较标记,例如:

bool findKeyWord(const std::string &str, const std::string &keyWord)
{
std::istringstring iss(str);
std::string token;
while (iss >> token)
{
if (token == keyWord)
return true;
}
return false;
}
std::string s1 = "IAmLookingForAwordU and I am the rest of the phrase";
std::string keyWord = "IAmLookingForAword";
if (findKeyWord(s1, keyWord)) {
// found...
}
else {
// not found...
}

你做对了。

对字符串进行标记,然后在解析时将每个标记大小与关键字大小进行比较。

如果find为true并且两个大小相等,则可以继续。额外的好处是,如果大小不匹配,您可以使用else块进行额外处理。

最新更新