Мне нужно определить, находится ли данное слово в другой строке или нет в c++.
мой прототип функции будет похож на bool check(string sentence, string word);
и "предложение" может быть похоже: word.someWord AND/OR/XOR word2.someWord *AND/OR/XOR* word3.someWord
и идет так.
Для реального примера: unlock_the_door.value = 1 AND turn_of_car.checkSum = 1
Теперь, В этом примере Если я назначаю слово для блокировки, моя функция проверки должна быть возвращена false, но если я дам ей "разблокировать", она должна вернуть значение true.
Для этого я использовал функцию.find(), но, как вы все знаете, это было неправильно, потому что вернуло меня к истине, даже если я дам блокировку в качестве параметра слова, так как "разблокировка" содержит "блокировку",
Думаю, мне нужно использовать регулярное выражение, но я не знаю, как это сделать. Кто-нибудь может мне помочь? Заранее спасибо.
Вы можете использовать С++ 11 regex_search
используя в качестве шаблона поиска свое слово, окруженное границей слов (\b
) или подчеркиванием.
#include <iostream>
#include <string>
using namespace std;
bool check(const string &sentence, const string &word) {
string boundary = "(_|\\b)";
return regex_search(sentence, regex(boundary + word + boundary));
}
int main () {
string sentence = "unlock_the_door.value=1 AND turn_of_car.checkSum=1";
cout << check(sentence, "lock") << endl;
cout << check(sentence, "unlock") << endl;
}
Если вы не хотите использовать С++ 11 или используете компилятор, который не поддерживает регулярное выражение С++ 11 (например, версии gcc до 4.9.0), вы можете использовать библиотеку Boost. Вам просто нужно загрузить библиотеку и добавить эти две строки в свой источник:
#include <boost/regex.hpp>
using namespace boost;
Также не забудьте передать опцию -lboost_regex
в gcc.
Я имею в виду, что подчеркивания - это пробелы.
#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <iterator>
#include <algorithm>
bool check( const std::string &sentence, const std::string &word )
{
std::istringstream is( sentence );
return std::find( std::istream_iterator<std::string>( is ),
std::istream_iterator<std::string>(),
word ) != std::istream_iterator<std::string>();
}
int main()
{
std::cout << std::boolalpha
<< check( "unlock the door.value=1 AND turn of car.checkSum=1", "lock" )
<< std::endl;
std::cout << std::boolalpha
<< check( "unlock the door.value=1 AND turn of car.checkSum=1", "unlock" )
<< std::endl;
return 0;
}
Выход
false
true
Если подчеркивания не являются пробелами, вы можете использовать ту же std::istringstream
и стандартную функцию std::getline
и проверить каждую прочитанную строку, равна ли она данной строке.
Или вы действительно можете разбить предложение на объект типа std::vector<std::string>
используя функцию-член find_first_of
Например
#include <iostream>
#include <iomanip>
#include <string>
bool check( const std::string &sentence, const std::string &word )
{
const char *delimiters = " _=.";
std::string::size_type first, last;
bool found = false;
first = 0;
while ( !found && first != std::string::npos )
{
first = sentence.find_first_not_of( delimiters, first );
if ( first != std::string::npos )
{
last = sentence.find_first_of( delimiters, first );
found = sentence.substr( first, last == std::string::npos ? last : last - first ) == word;
first = last;
}
}
return found;
}
int main()
{
std::string s = "unlock_the_door.value=1 AND turn_of_car.checkSum=1";
std::cout << std::boolalpha
<< check( s, "lock" )
<< std::endl;
std::cout << std::boolalpha
<< check( s, "unlock" )
<< std::endl;
return 0;
}
Выход
false
true
Сначала разделите предложение на слова, затем проверьте список, чтобы узнать, содержит ли оно точные слова (слова), которые вы ищете.
Вы также можете рассмотреть использование регулярных выражений и поиск слова (ов), каждый из которых предшествует любому запуску или пробелу в строке, а затем пробел, пунктуацию или конец строки.
Если я правильно понял, вы хотите узнать, содержится ли в предложении не только слово, но и слова в этом предложении. Вы можете сделать это следующим образом:
bool check (std::string sentence, std::string word)
{
std::string part;
for(unsigned int ii=0; ii<sentence.size()-word.size(); ii++)
{
part = sentence.substr(ii,word.size());
if(!part.compare(word)) {
return true;
}
}
return false;
}
Это проверяет каждую часть предложения, длина слова word.size(), если она равна слову. Если оно равно, это вернет true, иначе false.
Хорошо, что я написал раньше, возможно, именно то, чего вы не хотите. Если вы хотите сравнить только слова в предложении (что для вас слово, вам нужно подумать о разделителях), тогда вы можете сделать это так (вам нужно включить string.h):
bool check (std::string sentence, std::string word)
{
char *c_str_sentence = new char[sentence.size()+1]; //you need this cause string.c_str() will return const char* but strtok needs char*;
char *c_str_word = new char[word.size()+1];
strcpy(c_str_sentence,sentence.c_str());
strcpy(c_str_word,word.c_str());
bool is_contained = false;
const char *delimiters = " _=."; //any delimiter you wish;
char *part = strtok(c_str_sentence,delimiters);
while (part != NULL)
{
if(!strcmp(part,c_str_word)) {
is_contained = true;
break;
}
part = strtok(NULL,delimiters);
}
delete[] c_str_sentence;
delete[] c_str_word;
return is_contained;
}
Возвращает только true, если вы проверяете "разблокировать" не для "блокировки". Однако, указав разделители, вы можете указать, к чему вы хотите относиться как к слову, а что нет.
new[]
и никогда не освобождает ее с помощью delete[]
.
Разделите предложение под знаком подчеркивания как разделитель. И используйте функцию stricmp. Наверное, это должно решить.