Doxygen
Loading...
Searching...
No Matches
stringutil.h
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * Copyright (C) 1997-2024 by Dimitri van Heesch.
4 *
5 * Permission to use, copy, modify, and distribute this software and its
6 * documentation under the terms of the GNU General Public License is hereby
7 * granted. No representations are made about the suitability of this software
8 * for any purpose. It is provided "as is" without express or implied warranty.
9 * See the GNU General Public License for more details.
10 *
11 * Documents produced by Doxygen are derivative works derived from the
12 * input used in their production; they are not affected by this license.
13 *
14 */
15
16#ifndef STRINGUTIL_H
17#define STRINGUTIL_H
18
19#include <string>
20#include <string_view>
21
22#include "containers.h"
23#include "regex.h"
24
25/** @file
26 * @brief Some helper functions for std::string
27 */
28
29/** Replaces occurrences of substring \a toReplace in string \a s with string \a replaceWith.
30 * Modifies \a s in place.
31 */
32inline void substituteInplace(std::string &s,
33 std::string_view toReplace,std::string_view replaceWith)
34{
35 std::string buf;
36 size_t pos = 0;
37 size_t prevPos = 0;
38 buf.reserve(s.length());
39
40 while ((pos=s.find(toReplace, prevPos))!=std::string::npos)
41 {
42 buf.append(s, prevPos, pos - prevPos);
43 buf += replaceWith;
44 prevPos = pos + toReplace.length();
45 }
46 buf.append(s, prevPos, s.size() - prevPos);
47 s.swap(buf);
48}
49
50/** Returns a new string where occurrences of substring \a toReplace in string \a s are replaced by
51 * string \a replaceWith.
52 */
53inline std::string substituteStringView(std::string_view s,
54 std::string_view toReplace,std::string_view replaceWith)
55{
56 std::string buf;
57 size_t pos = 0;
58 size_t prevPos = 0;
59 buf.reserve(s.length());
60
61 while ((pos=s.find(toReplace, prevPos))!=std::string::npos)
62 {
63 buf.append(s, prevPos, pos - prevPos);
64 buf += replaceWith;
65 prevPos = pos + toReplace.length();
66 }
67 buf.append(s, prevPos, s.size() - prevPos);
68 return buf;
69}
70
71
72/** Given a string view \a s, returns a new, narrower view on that string, skipping over any
73 * leading or trailing whitespace characters.
74 */
75inline std::string_view stripWhiteSpace(std::string_view s)
76{
77 static auto isspace = [](char c){ return c==' ' || c=='\t' || c=='\n' || c=='\r'; };
78 size_t sl = s.length();
79 if (sl==0 || (!isspace(s[0]) && !isspace(s[sl-1]))) return s;
80 size_t start=0, end=sl-1;
81 while (start<sl && isspace(s[start])) start++;
82 if (start==sl) return s.substr(0,0); // only whitespace
83 while (end>start && isspace(s[end])) end--;
84 return s.substr(start,end+1-start);
85}
86
87inline void addTerminalCharIfMissing(std::string &s,char c)
88{
89 if (s.empty())
90 {
91 s+=c;
92 }
93 else
94 {
95 if (s[s.length()-1]!=c) s+=c;
96 }
97}
98
99/// returns true iff \a data points to a substring that matches string literal \a str
100template <size_t N>
101bool literal_at(const char *data,const char (&str)[N])
102{
103 size_t len = N-1; // exclude 0 terminator
104 return data!=nullptr && data[0]==str[0] && dstrncmp(data+1,str+1,len-1)==0;
105}
106
107/// returns true iff \a data points to a substring that matches string literal \a str
108template <size_t N>
109bool literal_at(std::string_view data,const char (&str)[N])
110{
111 size_t len = N-1; // exclude 0 terminator
112 return len<=data.size() && data[0]==str[0] && dstrncmp(data.data()+1,str+1,len-1)==0;
113}
114
115/// split input string \a s by string delimiter \a delimiter.
116/// returns a vector of non-empty strings that are between the delimiters
117inline StringVector split(const std::string &s,const std::string &delimiter)
118{
119 StringVector result;
120 size_t prev = 0, pos = 0, len = s.length();
121 do
122 {
123 pos = s.find(delimiter, prev);
124 if (pos == std::string::npos) pos = len;
125 if (pos>prev) result.push_back(s.substr(prev,pos-prev));
126 prev = pos + delimiter.length();
127 }
128 while (pos<len && prev<len);
129 return result;
130}
131
132/// split input string \a s by regular expression delimiter \a delimiter.
133/// returns a vector of non-empty strings that are between the delimiters
134inline StringVector split(const std::string &s,const reg::Ex &delimiter)
135{
136 StringVector result;
137 reg::Iterator iter(s, delimiter);
139 size_t p=0;
140 for ( ; iter != end; ++iter)
141 {
142 const auto &match = *iter;
143 size_t i=match.position();
144 size_t l=match.length();
145 if (i>p) result.push_back(s.substr(p,i-p));
146 p=i+l;
147 }
148 if (p<s.length()) result.push_back(s.substr(p));
149 return result;
150}
151
152/// create a string where the string in the vector are joined by the given delimiter
153inline std::string join(const StringVector &sv,const std::string &delimiter)
154{
155 std::string result;
156 bool first=true;
157 for (const auto &s : sv)
158 {
159 if (!first) result+=delimiter;
160 first=false;
161 result+=s;
162 }
163 return result;
164}
165
166/// find the index of a string in a vector of strings, returns std::string::npos if the string could not be found
167inline size_t findIndex(const StringVector &sv,const std::string &s)
168{
169 auto it = std::find(sv.begin(),sv.end(),s);
170 return it!=sv.end() ? static_cast<size_t>(it-sv.begin()) : std::string::npos;
171}
172
173/// find the index of the first occurrence of pattern \a re in a string \a s
174/// returns std::string::npos if the pattern could not be found
175inline size_t findIndex(const std::string &s,const reg::Ex &re)
176{
177 reg::Match match;
178 return reg::search(s,match,re) ? static_cast<size_t>(match.position()) : std::string::npos;
179}
180
181inline std::string removeEmptyLines(const std::string &s)
182{
183 std::string out;
184 out.reserve(s.length());
185 const char *p=s.data();
186 if (p)
187 {
188 char c = 0;
189 while ((c=*p++))
190 {
191 if (c=='\n')
192 {
193 const char *e = p;
194 while (*e==' ' || *e=='\t') e++;
195 if (*e=='\n')
196 {
197 p=e;
198 }
199 else out+=c;
200 }
201 else
202 {
203 out+=c;
204 }
205 }
206 }
207 return out;
208}
209
210
211#endif // STRINGUTIL_H
Class representing a regular expression.
Definition regex.h:39
Class to iterate through matches.
Definition regex.h:239
Object representing the matching results.
Definition regex.h:154
std::vector< std::string > StringVector
Definition containers.h:33
DirIterator end(const DirIterator &) noexcept
Definition dir.cpp:176
int dstrncmp(const char *str1, const char *str2, size_t len)
Definition dstring.h:60
bool search(std::string_view str, Match &match, const Ex &re, size_t pos)
Search in a given string str starting at position pos for a match against regular expression re.
Definition regex.cpp:847
std::string join(const StringVector &sv, const std::string &delimiter)
create a string where the string in the vector are joined by the given delimiter
Definition stringutil.h:153
std::string substituteStringView(std::string_view s, std::string_view toReplace, std::string_view replaceWith)
Returns a new string where occurrences of substring toReplace in string s are replaced by string repl...
Definition stringutil.h:53
void addTerminalCharIfMissing(std::string &s, char c)
Definition stringutil.h:87
size_t findIndex(const StringVector &sv, const std::string &s)
find the index of a string in a vector of strings, returns std::string::npos if the string could not ...
Definition stringutil.h:167
bool literal_at(const char *data, const char(&str)[N])
returns true iff data points to a substring that matches string literal str
Definition stringutil.h:101
std::string removeEmptyLines(const std::string &s)
Definition stringutil.h:181
void substituteInplace(std::string &s, std::string_view toReplace, std::string_view replaceWith)
Replaces occurrences of substring toReplace in string s with string replaceWith.
Definition stringutil.h:32
StringVector split(const std::string &s, const std::string &delimiter)
split input string s by string delimiter delimiter.
Definition stringutil.h:117
std::string_view stripWhiteSpace(std::string_view s)
Given a string view s, returns a new, narrower view on that string, skipping over any leading or trai...
Definition stringutil.h:75