Browse Source

split(), parseSepButNotBetween(), [lr]trim()

master
Odilitime 5 years ago
parent
commit
4fd458e697
  1. 120
      src/StringUtils.cpp
  2. 21
      src/StringUtils.h

120
src/StringUtils.cpp

@ -1,10 +1,8 @@ @@ -1,10 +1,8 @@
#include "StringUtils.h"
#include <algorithm>
#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>
/**
* get an extension from a filename
@ -88,3 +86,119 @@ const std::string toLowercase(const std::string &str) { @@ -88,3 +86,119 @@ const std::string toLowercase(const std::string &str) {
return s;
*/
}
std::vector<std::string> split(const std::string &text, char sep) {
std::vector<std::string> tokens;
std::size_t start = 0, end = 0;
while ((end = text.find(sep, start)) != std::string::npos) {
if (end != start) {
tokens.push_back(text.substr(start, end - start));
}
start = end + 1;
}
if (end != start) {
tokens.push_back(text.substr(start));
}
return tokens;
}
bool in_array(std::string needle, std::vector<std::string> haystack) {
for(auto it : haystack) {
if (it == needle) return true;
}
return false;
}
// FIXME: , in quotes or {} (JSON) <= top priority for 4chan
std::vector<std::string> parseSepButNotBetween(std::string string, std::string sep, std::vector<std::string> open, std::vector<std::string> close) {
std::vector<std::string> arr;
size_t mp = string.length();
std::string str3 = "";
size_t opens = 0;
size_t closes = 0;
for(int p = 0; p < mp; p++) {
auto next = string.find(sep, p); // find next comma after p
// if last string without a ,
if (next == std::string::npos) {
next = mp; // set to end
}
auto diff = next - p; // number of charaters to examine
std::string str2 = string.substr(p, diff); // get substring in this scan
for(auto o : open) {
opens += std::count(str2.begin(), str2.end(), o[0]);
}
for(auto c : close) {
closes += std::count(str2.begin(), str2.end(), c[0]);
}
str3 += str2;
bool flush = true;
if (opens != closes) {
str3 += sep;
flush = false;
}
if (flush) {
arr.push_back(str3);
str3 = "";
}
p += diff;
}
return arr;
}
/*
std::vector<std::string> parseCommas(std::string string, std::string sep, std::vector<std::string> quotes) {
std::vector<std::string> arr;
if (!quotes.size()) {
quotes.push_back("'");
quotes.push_back("\"");
}
size_t mp = string.length();
std::string str3 = "";
for(int p = 0; p < mp; p++) {
auto next = string.find(sep, p); // find next comma after p
// if last string without a ,
if (next == std::string::npos) {
next = mp; // set to end
}
auto diff = next - p; // number of charaters to examine
auto str2 = string.substr(p, diff); // get substring in this scan
auto open = str2.substr(0, 1);
str3 += str2;
bool flush = true;
if (in_array(open, quotes)) {
auto last = trim(str2).substr(-1, 1);
if (last!=open) {
str3 += ',';
flush = false;
}
}
if (flush) {
arr.push_back(str3);
str3 = "";
}
p += diff;
}
return arr;
}
size_t findMatching(std::string string, std::string opens, std::string closes, std::string escape="\\") {
// find open
auto opos = string.find(open);
if (opos == std::string::npos) {
return 0;
}
auto pos = opos;
while(pos != std::string::npos) {
auto cpos = string.find(close, pos+(open==close?1:0)); // don't want to end up with the opening marker as the start
if (escape!="") {
auto prevchar = string.substr(cpos - escape.length(), escape.length()); // get previous char before cpos
if (prevchar != escape) {
return cpos;
}
}
pos = cpos;
}
return 0;
}
*/

21
src/StringUtils.h

@ -9,5 +9,26 @@ const std::string getFilenameExtension(std::string const& fileName); @@ -9,5 +9,26 @@ const std::string getFilenameExtension(std::string const& fileName);
const std::string getDocumentFromURL(const std::string &url);
const std::string getHostFromURL(const std::string &url);
const std::string getSchemeFromURL(const std::string &url);
std::vector<std::string> split(const std::string &text, char sep);
std::vector<std::string> parseSepButNotBetween(std::string string, std::string sep, std::vector<std::string> open, std::vector<std::string> close);
// from https://stackoverflow.com/a/25385766/7697705
// trim from end of string (right)
inline std::string& rtrim(std::string& s, const char* t = " \t\n\r\f\v") {
s.erase(s.find_last_not_of(t) + 1);
return s;
}
// trim from beginning of string (left)
inline std::string& ltrim(std::string& s, const char* t = " \t\n\r\f\v") {
s.erase(0, s.find_first_not_of(t));
return s;
}
// trim from both ends of string (left & right)
inline std::string& trim(std::string& s, const char* t = " \t\n\r\f\v") {
return ltrim(rtrim(s, t), t);
}
#endif

Loading…
Cancel
Save