所以我必须将这句话分开:“你好,大家!这就是:COSC-1436,SP18”分成不同的标记,驳回任何标点符号减去短划线。所以输出应该是:
您好
大家
此
是
COSC-1436
SP18
然后我必须加密每个令牌,我已经覆盖了。我在使用多个分隔符时遇到了麻烦。这就是我目前所拥有的。
功能原型:
void tokenize(const string&, const string&, vector<string>&);
功能调用:
tokenize(code, " .,:;!?", tokens);
功能定义:
void tokenize(const string& str, const string& delim, vector<string>& tokens)
{
int tokenStart = 0;
int delimPos = str.find_first_of(delim);
while(delimPos != string::npos)
{
string tok = str.substr(tokenStart, delimPos - tokenStart);
tokens.push_back(tok);
delimPos++;
tokenStart = delimPos;
delimPos = str.find_first_of(delim, delimPos);
if(delimPos == string::npos)
{
string tok = str.substr(tokenStart, delimPos - tokenStart);
tokens.push_back(tok);
}
}
}
唯一的问题是现在有令牌为空格,程序遇到标点符号。有什么建议吗?
答案 0 :(得分:4)
您可以使用std::regex_iterator
,因为这正是它的设计目标。
#include <regex>
#include <iostream>
#include <string>
int main()
{
const std::string s = "Hello, everyone! This is: COSC-1436, SP18";
std::regex words_regex("[^\\s.,:;!?]+");
auto words_begin = std::sregex_iterator(s.begin(), s.end(), words_regex);
auto words_end = std::sregex_iterator();
for (std::sregex_iterator i = words_begin; i != words_end; ++i)
std::cout << (*i).str() << '\n';
}
完整程序的输出将是这个。
Hello
everyone
This
is
COSC-1436
SP18
答案 1 :(得分:0)
找到分隔符后,应将子字符串start移动到first_not_of
分隔符的char。基本上改变了:
delimPos++;
为:
delimPos = str.find_first_not_of(delim, delimPos + 1);
这将确保当您依次有2个或更多分隔符时,delimPos
会移到最后一个分隔符之后。
或者你可以试试这个:
#include <iostream>
#include <string>
int main()
{
std::string str = "Hello, everyone! This is: COSC-1436, SP18";
std::string const delims{ " .,:;!?" };
size_t beg, pos = 0;
while ((beg = str.find_first_not_of(delims, pos)) != std::string::npos)
{
pos = str.find_first_of(delims, beg + 1);
std::cout << str.substr(beg, pos - beg) << std::endl;
}
return 0;
}
Hello
everyone
This
is
COSC-1436
SP18