[英]How To Extract Tokens from String?
編輯:有人可以添加正則表達式解決方案嗎? 我正在查看以下正則表達式:
[\(\)!*-+^]
我有一個 function 根據我在正文中聲明的特殊字符從文本中提取標記。
function有2個問題:
1)它不打印特殊字符。
2)當兩個特殊字符彼此相鄰時輸出錯誤
所以我做了一個改變,解決了問題 1(正如我從一些測試的結果中看到的)但沒有解決問題 2,有什么幫助嗎?
注意:我使用的是 C++11 標准,不打算使用 boost
示例:給定: a+(b*c)
我期待: a,+,(,b,*,c,)
給定: a+b
我期待: a,+,b
給定: ab+
我期待: ab,+
給定: a b+
我期待: ab,+
你沒有很好地處理空字符串。 在處理空字符串之前,請檢查以確保它不為空。
#include <sstream>
#include <string>
#include <vector>
#include <cassert>
using std::string;
using std::stringstream;
using std::vector;
namespace {
// Parse a string into a vector of tokens by special characters.
auto find(string str) -> vector<string> {
auto result = vector<string>{};
auto pos = string::size_type{};
auto last_pos = string::size_type{};
while ((pos = str.find_first_of("+^-*!()", last_pos)) != string::npos) {
// Is there a token before the special character?
if (pos - last_pos > 0) {
result.push_back(str.substr(last_pos, pos - last_pos));
}
last_pos = pos + 1;
// Add the special character as a token.
result.push_back(str.substr(pos, 1));
}
auto last = str.substr(last_pos);
// Is there a trailing token after the last found special character?
if (!last.empty()) {
result.push_back(str.substr(last_pos));
}
return result;
}
// Helper routine.
// Join a vector of strings together using a given separator.
auto join(vector<string> const& v, string sep) -> string {
auto ss = stringstream{};
auto first = true;
for (auto const& s : v) {
if (first) {
ss << s;
first = false;
} else {
ss << sep << s;
}
}
return ss.str();
}
// Helper routine.
// Returns a string representing the tokenized string.
auto check(string s) -> string {
auto v = find(s);
auto result = join(v, ",");
return result;
}
} // anon
int main() {
// Unit tests to check that the string parses and tokenizes into the expected string.
assert(check("a+(b*c)") == "a,+,(,b,*,c,)");
assert(check("a+b") == "a,+,b");
assert(check("ab+") == "ab,+");
assert(check("a b+") == "a b,+");
assert(check("a") == "a");
assert(check("aa") == "aa");
assert(check("+") == "+");
assert(check("++") == "+,+");
assert(check("a+") == "a,+");
assert(check("+a") == "+,a");
assert(check("") == "");
}
這是一個應該解析您想要的令牌的正則表達式解決方案:
void find(std::string str)
{
static const std::regex r(R"(\+|\^|-|\*|!|\(|\)|([\w|\s]+))");
std::copy( std::sregex_token_iterator(str.begin(), str.end(), r, 0),
std::sregex_token_iterator(),
std::ostream_iterator<std::string>(std::cout, "\n"));
}
這是一個演示。
這里有一個解釋。
請注意,如果您想進行通用解析,這不是一個好主意。 正則表達式將很快變得笨拙(如果還沒有的話),並且有更好的工具可以為您執行此操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.