📄 mstring.cxx
字号:
Get the next token from string @return: the next position in string to be continue or string::npos if no more tokens @param dst Pointer to the destination string. If this parameter is null the function may be used to counting tokens @param start Start position of the string - 0 or the previous returned value @param sep String with possible separators. Every symbol of this string is separator @param quote String with quotation symbols, for example, "'" Inside quote string is not divided. Quotation can start with any of these symbols, but finish with the same symbol only. @param pair_chr Usually '\' symbol to include quotation symbols inside the quote parts @param sep_flag Flag sep_single or sep_multiple to determine, whether the separators, going successively are nerpreted as detached empty tokens (sep_single) or one token (sep_multiple), as strtok does. sep_single: string "123,,456" will be "123", "", "456" sep_multiple: string "123,,456" will be "123", "456" \\================================================================================*/ string::size_type mstring::token(string *dst, size_type start, const string &sep, const string "e, char pair_chr, sep_flag flag) const { size_type count = 0; char quote_chr = 0; if(dst) dst->erase(); if(start == string::npos) return string::npos; const char *pstr = c_str() + start; if(*pstr == 0) return string::npos; size_type sep_len = 1; if(flag == sep_whole_str) sep_len = sep.length(); const char *psep = sep.c_str(); if(flag == sep_multiple) { //Pass all the separators symbols at the begin of the string while(*pstr && sep.find(*pstr) != string::npos) { ++pstr; ++start; } } for(count = 0;;count++) { char c = *pstr; bool found = false; //Outside quote find one of separator symbols if(quote_chr == 0) { if(sep_len == 1) { found = sep.find(c) != string::npos; } else { found = strncmp(psep, pstr, sep_len) == 0; //sep.compare(0, sep_len, pstr, sep_len) == 0; } } ++pstr; if(c == 0 || found) { if(dst) dst->assign(*this, start, count); //The next time it will be the next separator character //But we must check, whether it is the end of the string. start += count; if(c) start += sep_len; break; } //Switch quote. If it is not a quote yet, try to check any of //quote symbols. Otherwise quote must be finished with quote_symb if(quote_chr == 0) { if(quote.find(c) != string::npos) { quote_chr = c; continue; } } else { //Inside quote pass all the pair symbols if(pair_chr && c == pair_chr) { if(*pstr) { ++count; ++pstr; } continue; } if(c == quote_chr) { quote_chr = 0; continue; } } } return start; } //------------------------------------------------------------------------------------- /** Split up the string into the many pieces. This function uses token function. @return Number of found tokens @param str_vec Pointer to the destination vector of strings. If this parameter is null the function may be used to counting tokens @param sep String with possible separators. Every symbol of this string is separator @param quote String with quotation symbols, for example, "'" Inside quote string is not divided. Quotation can start with any of this symbol, but finish with the same symbol only. @param pair_chr Usually '\' symbol to include quotation symbols inside the quote parts @param flag Flag sep_single or sep_multiple to determine, whether the separators, going successively are nerpreted as detached empty tokens (sep_single) or one token (sep_multiple), as strtok does. sep_single: string "123,,456" will be "123", "", "456" sep_multiple: string "123,,456" will be "123", "456" \\================================================================================*/ unsigned mstring::split(mstr_vector *str_vec, const string &sep, const string "e, char pair_chr, sep_flag flag) const { if(str_vec) str_vec->clear(); unsigned count = 0; size_type start = 0; mstring tmp; while((start = token(&tmp, start, sep, quote, pair_chr, flag)) != string::npos) { if(str_vec) str_vec->push_back(tmp); count++; } return count; } //------------------------------------------------------------------------------------- /** Check quote parts balance. @return true = balance OK, false - no balance @param quote String with quotation symbols, for example, "'" Quotation can start with any of this symbol, but finish with the same symbol only. @param pair_chr Usually '\' symbol to include quotation symbols inside the quote parts \\================================================================================*/ bool mstring::chkquote(const string "e, char pair_chr) const { char quote_chr = 0; const char *pstr = c_str(); char c; while((c = *pstr++) != 0) { //Switch quote. If it is not a quote yet, try to check any of //quote symbols. Otherwise quote must be finished with quote_symb if(quote_chr == 0) { if(quote.find(c) != string::npos) { quote_chr = c; continue; } } else { //Inside quote pass all the pair symbols if(pair_chr && c == pair_chr) { if(*pstr) { ++pstr; } continue; } if(c == quote_chr) { quote_chr = 0; continue; } } } return quote_chr == 0; } //------------------------------------------------------------------------------------- /** Get the next BRACKET token from string. Parsing nested brackets can be done recursively. For example: \begin{verbatim} void print_brackets(int ident, std::mstring str, std::string "e, char pair) { std::mstring tmp; std::string::size_type start = 0; int bal; while((start = str.brtok(&tmp, start, &bal, '+', '-', quote, pair)) != std::string::npos) { for(unsigned i = 0; i < ident; i++) cout << '*'; cout << tmp.c_str() << " = " << bal << "\n"; print_brackets(ident+1, tmp, quote, pair); } } \end{verbatim} @return the next position in string to be continue or string::npos if no more tokens @param dst Pointer to the destination string. If this parameter is null the function may be used to counting tokens @param start Start position in the string - 0 or the previous returned value @param balance Returns bracket balance positive - a lake of closing brackets negatine - an overage of closing brackets @param br_open Open bracket character @param br_close Close bracket character @param quote String with quotation symbols, for example, "'" Inside quote string is not divided. Quotation can start with any of this symbol, but finish with the same symbol only. @param pair_chr Usually '\' symbol to include quotation symbols inside the quote parts \\================================================================================*/ string::size_type mstring::brtok(string *dst, size_type *start, int *balance, char br_open, char br_close, const string "e, char pair_chr) const { int brbal = 0; char quote_chr = 0; size_type count = 0; size_type start_pos = string::npos; size_type end_pos = string::npos; if(dst) dst->erase(); if(*start == string::npos) return string::npos; const char *pstr = c_str() + *start; if(*pstr == 0) return string::npos; char c; for(count = 0; (c = *pstr++) != 0; count++) { //Outside quote find a bracket if(quote_chr == 0) { if(c == br_open) { if(start_pos == string::npos && brbal == 0) start_pos = count; brbal++; } if(c == br_close) { brbal--; if(end_pos == string::npos && brbal == 0) end_pos = count; } } //Switch quote. If it is not a quote yet, try to check any of //quote symbols. Otherwise quote must be finished with quote_symb if(quote_chr == 0) { if(quote.find(c) != string::npos) { quote_chr = c; continue; } } else { //Inside quote pass all the pair symbols if(pair_chr && c == pair_chr) { if(*pstr) { ++count; ++pstr; } continue; } if(c == quote_chr) { quote_chr = 0; continue; } } } if(start_pos != string::npos && end_pos != string::npos) { if(dst) dst->assign(*this, *start + start_pos + 1, end_pos - start_pos - 1); ++end_pos; } if(balance) *balance = brbal; if(end_pos == string::npos) return npos; end_pos += *start; *start += start_pos; return end_pos; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -