RegExp.h
1 /*
2 
3 MIT License
4 
5 Copyright (c) 2017 FMI Open Development / Markus Peura, first.last@fmi.fi
6 
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
13 
14 The above copyright notice and this permission notice shall be included in all
15 copies or substantial portions of the Software.
16 
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 SOFTWARE.
24 
25 */
26 /*
27 Part of Rack development has been done in the BALTRAD projects part-financed
28 by the European Union (European Regional Development Fund and European
29 Neighbourhood Partnership Instrument, Baltic Sea Region Programme 2007-2013)
30 */
31 #ifndef REGEXP_H__
32 #define REGEXP_H__ "deer::RegExp v0.1 Dec 2004 Markus.Peura@fmi.fi"
33 
34 #include <string>
35 #include <sstream>
36 #include <iostream>
37 #include <vector>
38 
39 #include <regex.h> // wants malloc?
40 
41 // g++ deer_regexp.cpp -o deer_regexp
42 // typedef size_t int;
43 // // using namespace std;
44 
45 namespace drain {
46 
58 class RegExp { //: public vector<string> {
59 public:
60 
62  //RegExp(const char *toStr = "");
63 
65  //RegExp(const char *toStr = "",int flags = REG_EXTENDED);
66  RegExp(const std::string &str = "", int flags = REG_EXTENDED);
67 
69  // Lack of this caused memory leakages.
70  RegExp(const RegExp &r);
71 
73  virtual
74  ~RegExp();
75 
76  //RegExp &operator=(const char *toStr);
77  RegExp &operator=(const std::string &str);
78  RegExp &operator=(const RegExp &r);
79 
80  // bool exp(const char *toStr);
81  bool setExpression(const std::string & str, int flags = REG_EXTENDED);
82 
83  // Compare with \see reset()
84  inline
85  void clear(){ writableResult.clear(); };
86 
87  inline
88  bool isSet() const {
89  return !regExpString.empty();
90  };
91 
92  inline
93  void reset(){
94  setExpression("");
95  };
96 
98  inline
99  bool empty() const {
100  return regExpString.empty();
101  };
102 
103 
104 
105  void setFlags(int flags){
106  this->flags = flags;
107  };
108 
110  const std::vector<std::string> & result;
111 
113  bool test(const std::string & str) const;
114 
116 
124  template <class T>
125  int execute(const std::string & str, T & result) const;
126 
128  // somewhat questionable whether should be const.
129  int execute(const std::string & str) const {
130  return execute(str, writableResult);
131  }
132 
134 
137  inline
138  void replace(const std::string &src, const std::string &replacement, std::string & dst) const {
139  std::stringstream sstr;
140  replace(src, replacement, sstr);
141  dst = sstr.str();
142  }
143 
144 
145  void replace(const std::string &src, const std::string &replacement, std::ostream & sstr) const;
146 
148  static inline
149  //void RegExp::replace(const std::string &src, std::string & dst) { //,std::string &dst){
150  void replace(const std::string &src, const std::string &regexp, const std::string &replacement, std::string & dst){
151  RegExp r(std::string("(^.*)?(") + regexp + std::string(")(.*$)?"));
152  r.replace(src, replacement, dst);
153  return; // r.replace(src, dst);
154  };
155 
156 
157 
158  inline
159  const std::string & toStr() const {
160  return regExpString;
161  };
162 
163  int flags;
164 
166  typedef std::vector<std::string> result_t;
167 
168 
169 protected:
170 
171 
172 
173  regex_t regExpBinary; // this is weird FIXME: check pointer aspect
174 
175  std::string regExpString;
176 
177  mutable result_t writableResult;
178 
179 private:
180  int expectedMatchCount() const;
181 };
182 
183 std::ostream & operator<<(std::ostream &ostr, const drain::RegExp & r);
184 
185 
186 template <class T>
187 int RegExp::execute(const std::string &src, T & result) const {
188 
190  const size_t n = regExpBinary.re_nsub + 1;
191  // cerr << "binary has subs:" << regExpBinary.re_nsub << endl;
192 
193  result.clear();
194  //result.resize(n);
195 
196  //cout << "resize => " << this->size() << endl;
197 
199  std::vector<regmatch_t> pmatch(n);
200 
206 
207  //cerr << "\nTrying " << toStr.c_str() << endl;
208  int resultCode = regexec(&regExpBinary, src.c_str(), pmatch.size(), &pmatch[0], 0) ;
209 
210  if (resultCode != REG_NOMATCH){
211  for (std::vector<regmatch_t>::const_iterator it = pmatch.begin(); it < pmatch.end(); ++it) {
212  const regmatch_t &m = *it;
213  if (m.rm_so != -1){
214  result.push_back(src.substr(m.rm_so, m.rm_eo - m.rm_so));
215  }
216  }
217  }
218 
219  //delete[] pmatch; // valgrind herjasi muodosta: delete pmatch
220  return resultCode;
221 
222 }
223 
224 } // drain
225 
226 
227 #endif
228 
229 // Drain
Definition: RegExp.h:58
static void replace(const std::string &src, const std::string &regexp, const std::string &replacement, std::string &dst)
Replaces std::string segment matching search to the given std::string.
Definition: RegExp.h:150
std::vector< std::string > result_t
Native result type, also for external result object.
Definition: RegExp.h:166
bool empty() const
Returns true, if expression is empty.
Definition: RegExp.h:99
const std::vector< std::string > & result
Public interface for the result.
Definition: RegExp.h:107
RegExp(const std::string &str="", int flags=REG_EXTENDED)
Constructor.
Definition: RegExp.cpp:59
int execute(const std::string &str, T &result) const
Apply regexp matching in a string. Returns 0 on success, REG_NOMATCH on failure.
Definition: RegExp.h:187
void replace(const std::string &src, const std::string &replacement, std::string &dst) const
Replaces std::string segment matching search regexp to the given std::string.
Definition: RegExp.h:138
int execute(const std::string &str) const
Variant using internal vector.
Definition: RegExp.h:129
virtual ~RegExp()
Destructor.
Definition: RegExp.cpp:70
bool test(const std::string &str) const
Tests if the regular expression accepts the given std::string.
Definition: RegExp.cpp:128
Definition: DataSelector.cpp:1277