sptk2 logo
SPTK Home Page
RegularExpression.h
1/*
2╔══════════════════════════════════════════════════════════════════════════════╗
3║ SIMPLY POWERFUL TOOLKIT (SPTK) ║
4╟──────────────────────────────────────────────────────────────────────────────╢
5║ copyright © 1999-2022 Alexey Parshin. All rights reserved. ║
6║ email alexeyp@gmail.com ║
7╚══════════════════════════════════════════════════════════════════════════════╝
8┌──────────────────────────────────────────────────────────────────────────────┐
9│ This library is free software; you can redistribute it and/or modify it │
10│ under the terms of the GNU Library General Public License as published by │
11│ the Free Software Foundation; either version 2 of the License, or (at your │
12│ option) any later version. │
13│ │
14│ This library is distributed in the hope that it will be useful, but │
15│ WITHOUT ANY WARRANTY; without even the implied warranty of │
16│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library │
17│ General Public License for more details. │
18│ │
19│ You should have received a copy of the GNU Library General Public License │
20│ along with this library; if not, write to the Free Software Foundation, │
21│ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. │
22│ │
23│ Please report all bugs and problems to alexeyp@gmail.com. │
24└──────────────────────────────────────────────────────────────────────────────┘
25*/
26
27#pragma once
28
29#include <sptk5/Strings.h>
30#include <sptk5/sptk-config.h>
31#include <sptk5/sptk.h>
32
33#include <atomic>
34#include <functional>
35#include <memory>
36#include <vector>
37
38#ifdef HAVE_PCRE2
39#define PCRE2_STATIC
40#define PCRE2_CODE_UNIT_WIDTH 8
41
42#include <pcre2.h>
43
44#define SPRE_CASELESS PCRE2_CASELESS
45#define SPRE_MULTILINE PCRE2_MULTILINE
46#define SPRE_DOTALL PCRE2_DOTALL
47#define SPRE_EXTENDED PCRE2_EXTENDED
48using pcre_offset_t = long;
49#endif
50
51#ifdef HAVE_PCRE
52
53#include <pcre.h>
54
55#define SPRE_CASELESS PCRE_CASELESS
56#define SPRE_MULTILINE PCRE_MULTILINE
57#define SPRE_DOTALL PCRE_DOTALL
58#define SPRE_EXTENDED PCRE_EXTENDED
59using pcre_offset_t = int;
60#endif
61
62#if defined(HAVE_PCRE2) | defined(HAVE_PCRE)
63
64namespace sptk {
65
71class MatchData;
72
76class SP_EXPORT RegularExpression
77{
78
79#ifdef HAVE_PCRE2
80 using PCREHandle = pcre2_code;
81 using PCREExtraHandle = uint8_t*;
82#else
83 using PCREHandle = pcre;
84 using PCREExtraHandle = pcre_extra;
85#endif
86
87public:
91 class SP_EXPORT Group
92 {
93 public:
100 Group(String value, pcre_offset_t start, pcre_offset_t end)
101 : value(move(value))
102 , start(start)
103 , end(end)
104 {
105 }
106
110 Group() = default;
111
112 String value;
113 pcre_offset_t start {0};
114 pcre_offset_t end {0};
115 };
116
121 class SP_EXPORT Groups
122 {
123 friend class RegularExpression;
124
125 public:
132 const Group& operator[](int index) const;
133
140 const Group& operator[](const char* name) const;
141
146 const std::vector<Group>& groups() const
147 {
148 return m_groups;
149 }
150
155 const std::map<String, Group>& namedGroups() const
156 {
157 return m_namedGroups;
158 }
159
163 bool empty() const
164 {
165 return m_groups.empty();
166 }
167
171 explicit operator bool() const
172 {
173 return !m_groups.empty();
174 }
175
176 protected:
181 void grow(size_t groupCount);
182
187 void add(Group&& group)
188 {
189 m_groups.push_back(std::move(group));
190 }
191
197 void add(const String& name, Group&& group)
198 {
199 m_namedGroups[name] = std::move(group);
200 }
201
202 private:
206 void clear();
207
208 std::vector<Group> m_groups;
209 std::map<String, Group> m_namedGroups;
210 static const Group emptyGroup;
211 };
212
225 explicit RegularExpression(const String& pattern, const String& options = "");
226
232 bool operator==(const String& text) const;
233
239 bool operator!=(const String& text) const;
240
246 bool matches(const String& text) const;
247
253 Groups m(const String& text) const
254 {
255 size_t offset = 0;
256 return m(text, offset);
257 }
258
265 Groups m(const String& text, size_t& offset) const;
266
273 String s(const String& text, const String& outputPattern) const;
274
282 String s(const String& text, const std::function<String(const String&)>& replace, bool& replaced) const;
283
289 Strings split(const String& text) const;
290
298 String replaceAll(const String& text, const String& outputPattern, bool& replaced) const;
299
307 String replaceAll(const String& text, const std::map<String, String>& substitutions, bool& replaced) const;
308
313 const String& pattern() const;
314
315private:
316 String m_pattern;
317 bool m_global {false};
318 String m_error;
319
320 std::shared_ptr<PCREHandle> m_pcre;
321 std::shared_ptr<PCREExtraHandle> m_pcreExtra;
322
323 uint32_t m_options {0};
324 size_t m_captureCount {0};
325
329 void compile();
330
338 size_t nextMatch(const String& text, size_t& offset, MatchData& matchData) const;
339
344 size_t getCaptureCount() const;
345
350 size_t getNamedGroupCount() const;
351
356 void getNameTable(const char*& nameTable, int& nameEntrySize) const;
357
364 static size_t findNextPlaceholder(size_t pos, const String& outputPattern);
365
366 void extractNamedMatches(const String& text, Groups& matchedStrings, const MatchData& matchData,
367 size_t matchCount) const;
368};
369
370using SRegularExpression = std::shared_ptr<RegularExpression>;
371
375} // namespace sptk
376
377#endif
SP_EXPORT bool operator==(const sptk::DateTime &dt1, const sptk::DateTime &dt2)
SP_EXPORT bool operator!=(const sptk::DateTime &dt1, const sptk::DateTime &dt2)

Fri Oct 14 2022 09:58:32: SPTK 5.4.1