Console Library 8.0.0
A header-only library that makes C++ simple
Loading...
Searching...
No Matches
re.h
Go to the documentation of this file.
1
9
10/*
11Copyright (c) 2026 MrXie1109
12
13Permission is hereby granted, free of charge, to any person obtaining a copy
14of this software and associated documentation files (the "Software"), to deal
15in the Software without restriction, including without limitation the rights
16to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17copies of the Software, and to permit persons to whom the Software is
18furnished to do so, subject to the following conditions:
19
20The above copyright notice and this permission notice shall be included in all
21copies or substantial portions of the Software.
22
23THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29SOFTWARE.
30*/
31
32#pragma once
33#include <iostream>
34#include <regex>
35#include <string>
36#include <vector>
37
38#include "../util/iter.h"
39
40namespace console {
47 template <class CharT = char, class Traits = std::char_traits<CharT>>
48 class BasicRegex {
49 public:
51 using string_type = std::basic_string<CharT, Traits>;
53 using regex_type = std::basic_regex<CharT>;
56 = std::match_results<typename string_type::const_iterator>;
58 using flag_type = typename regex_type::flag_type;
60 using iterator_type
61 = std::regex_iterator<typename string_type::const_iterator,
62 CharT,
63 std::regex_traits<CharT>>;
65 using token_iterator
66 = std::regex_token_iterator<typename string_type::const_iterator,
67 CharT,
68 std::regex_traits<CharT>>;
69
70 private:
72
73 public:
76 * @param pat 正则表达式模式字符串。
77 * @param flags 正则表达式标志,默认为ECMAScript。
78 */
79 BasicRegex(const string_type &pat,
80 flag_type flags = regex_type::ECMAScript) : pattern(pat, flags) {}
81
83 * @class Match
84 * @brief 匹配结果对象,保存文本副本和位置信息,不依赖迭代器有效性。
85 */
86 class Match {
87 private:
89 struct GroupInfo {
90 std::ptrdiff_t pos;
91 std::ptrdiff_t len;
92 };
93 std::vector<GroupInfo> groups_;
94 bool success;
95
96 public:
100 Match() : success(false) {}
101
104 * @param t 文本副本。
105 * @param m 匹配结果。
106 */
107 Match(string_type t, const match_type &m) :
108 text_copy(std::move(t)), success(true) {
109 for (size_t i = 0; i < m.size(); ++i)
110 groups_.push_back({m.position(i), m.length(i)});
111 }
112
115 * @param n 组的索引,默认为 0。
116 * @return 匹配成功时返回组的子串,否则返回空字符串。
117 */
118 string_type group(int n = 0) const {
119 if (!success || n < 0 || n >= int(groups_.size()))
120 return string_type{};
121 return text_copy.substr(groups_[n].pos, groups_[n].len);
122 }
123
125 * @brief 获取所有组的子串。
126 * @return 匹配成功时返回所有组的子串列表,否则返回空列表。
127 */
128 std::vector<string_type> groups() const {
129 std::vector<string_type> result;
130 if (!success) return result;
131 for (size_t i = 1; i < groups_.size(); ++i)
132 result.push_back(
133 text_copy.substr(groups_[i].pos, groups_[i].len));
134 return result;
135 }
136
139 * @param n 组的索引,默认为 0。
140 * @return 匹配成功时返回组的起始位置,否则返回 -1。
141 */
142 int start(int n = 0) const {
143 if (!success || n < 0 || n >= int(groups_.size())) return -1;
144 return int(groups_[n].pos);
145 }
146
149 * @param n 组的索引,默认为 0。
150 * @return 匹配成功时返回组的结束位置,否则返回 -1。
151 */
152 int end(int n = 0) const {
153 if (!success || n < 0 || n >= int(groups_.size())) return -1;
154 return int(groups_[n].pos + groups_[n].len);
155 }
156
159 * @param n 组的索引,默认为 0。
160 * @return 匹配成功时返回组的起始和结束位置,否则返回 (-1, -1)。
161 */
162 std::pair<int, int> span(int n = 0) const {
163 return {start(n), end(n)};
164 }
165
169
170 explicit operator bool() const { return success; }
171 };
172
175 * @param text 要搜索的文本。
176 * @return 匹配成功时返回匹配对象,否则返回空对象。
177 */
178 Match search(string_type text) const {
179 match_type m;
180 auto copy = text;
181 if (std::regex_search(copy, m, pattern))
182 return Match(std::move(copy), m);
183 return Match();
184 }
185
188 * @param text 要匹配的文本。
189 * @return 匹配成功时返回匹配对象,否则返回空对象。
190 */
191 Match match(string_type text) const {
192 match_type m;
193 auto copy = text;
194 if (std::regex_match(copy, m, pattern))
195 return Match(std::move(copy), m);
196 return Match();
197 }
198
204 Match fullmatch(const string_type &text) const { return match(text); }
205
208 * @param text 要搜索的文本。
209 * @return 匹配成功时返回匹配对象列表,否则返回空列表。
210 */
211 std::vector<string_type> findall(const string_type &text) const {
212 std::vector<string_type> result;
213 auto begin = iterator_type(text.begin(), text.end(), pattern);
214 auto end = iterator_type();
215 for (auto it = begin; it != end; ++it) result.push_back(it->str());
216 return result;
217 }
218
223 * @return 分割后的字符串列表。
224 */
225 std::vector<string_type>
226 split(const string_type &text, int maxsplit = 0) const {
227 std::vector<string_type> result;
228 token_iterator it(text.begin(), text.end(), pattern, -1);
229 token_iterator end;
230 int count = 0;
231 for (; it != end && (maxsplit <= 0 || count < maxsplit);
232 ++it, ++count)
233 result.push_back(*it);
234 if (maxsplit > 0 && count == maxsplit && it != end)
235 result.push_back(string_type((*it).first, text.end()));
236 return result;
237 }
238
243 * @param count 替换次数,默认为 0 表示替换所有匹配。
244 * @return 替换后的字符串。
245 */
246 string_type sub(const string_type &repl,
247 const string_type &text,
248 int count = 0) const {
249 if (count <= 0) return std::regex_replace(text, pattern, repl);
250 string_type result;
251 auto begin = iterator_type(text.begin(), text.end(), pattern);
252 auto end = iterator_type();
253 auto last = text.begin();
254 int replaced = 0;
255 for (auto it = begin; it != end && replaced < count;
256 ++it, ++replaced) {
257 result.append(last, text.begin() + it->position());
258 result.append(repl);
259 last = text.begin() + it->position() + it->length();
260 }
261 result.append(last, text.end());
262 return result;
263 }
264
269 * @param count 替换次数,默认为 0 表示替换所有匹配。
270 * @return 替换后的字符串和替换次数的对。
271 */
272 std::pair<string_type, int> subn(const string_type &repl,
273 const string_type &text,
274 int count = 0) const {
275 if (count <= 0) {
276 auto result = std::regex_replace(text, pattern, repl);
277 auto begin = iterator_type(text.begin(), text.end(), pattern);
278 auto end = iterator_type();
279 int cnt = int(std::distance(begin, end));
280 return {result, cnt};
281 }
282 string_type result;
283 auto begin = iterator_type(text.begin(), text.end(), pattern);
284 auto end = iterator_type();
285 auto last = text.begin();
286 int replaced = 0;
287 for (auto it = begin; it != end && replaced < count;
288 ++it, ++replaced) {
289 result.append(last, text.begin() + it->position());
290 result.append(repl);
291 last = text.begin() + it->position() + it->length();
292 }
293 result.append(last, text.end());
294 return {result, replaced};
295 }
296 };
297
300
301 namespace re {
308 inline Regex compile(const std::string &pattern,
309 std::regex::flag_type flags = std::regex::ECMAScript) {
310 return Regex(pattern, flags);
311 }
312
319 inline WRegex compile(const std::wstring &pattern,
320 std::wregex::flag_type flags = std::wregex::ECMAScript) {
321 return WRegex(pattern, flags);
322 }
323
330 inline Regex::Match
331 search(const std::string &pattern, const std::string &text) {
332 return Regex(pattern).search(text);
333 }
334
341 inline WRegex::Match
342 search(const std::wstring &pattern, const std::wstring &text) {
343 return WRegex(pattern).search(text);
344 }
345
352 inline Regex::Match
353 match(const std::string &pattern, const std::string &text) {
354 return Regex(pattern).match(text);
355 }
356
363 inline WRegex::Match
364 match(const std::wstring &pattern, const std::wstring &text) {
365 return WRegex(pattern).match(text);
366 }
367
374 inline std::vector<std::string>
375 findall(const std::string &pattern, const std::string &text) {
376 return Regex(pattern).findall(text);
377 }
378
385 inline std::vector<std::wstring>
386 findall(const std::wstring &pattern, const std::wstring &text) {
387 return WRegex(pattern).findall(text);
388 }
389
397 inline std::vector<std::string> split(const std::string &pattern,
398 const std::string &text,
399 int maxsplit = 0) {
400 return Regex(pattern).split(text, maxsplit);
401 }
402
410 inline std::vector<std::wstring> split(const std::wstring &pattern,
411 const std::wstring &text,
412 int maxsplit = 0) {
413 return WRegex(pattern).split(text, maxsplit);
414 }
415
424 inline std::string sub(const std::string &pattern,
425 const std::string &repl,
426 const std::string &text,
427 int count = 0) {
428 return Regex(pattern).sub(repl, text, count);
429 }
430
439 inline std::wstring sub(const std::wstring &pattern,
440 const std::wstring &repl,
441 const std::wstring &text,
442 int count = 0) {
443 return WRegex(pattern).sub(repl, text, count);
444 }
445
451 inline std::string escape(const std::string &s) {
452 static std::regex special(R"([.^$*+?()\‍[\‍]{}|\\‍])");
453 return std::regex_replace(s, special, R"(\$&)");
454 }
455
461 inline std::wstring escape(const std::wstring &s) {
462 static std::wregex special(LR"([.^$*+?()\‍[\‍]{}|\\‍])");
463 return std::regex_replace(s, special, LR"(\$&)");
464 }
465 }
466}
string_type text_copy
文本副本。
Definition re.h:85
bool success
匹配成功标志。
Definition re.h:91
int start(int n=0) const
获取指定组的起始位置。
Definition re.h:139
int end(int n=0) const
获取指定组的结束位置。
Definition re.h:149
std::vector< GroupInfo > groups_
组信息列表。
Definition re.h:90
Match()
默认构造函数,创建一个空的匹配结果。
Definition re.h:97
std::pair< int, int > span(int n=0) const
获取指定组的起始和结束位置。
Definition re.h:159
string_type group(int n=0) const
获取指定组的子串。
Definition re.h:115
std::vector< string_type > groups() const
获取所有组的子串。
Definition re.h:125
正则表达式对象,封装编译后的模式,提供匹配、搜索、替换等功能。
Definition re.h:48
Match fullmatch(const string_type &text) const
Definition re.h:201
std::basic_regex< CharT > regex_type
正则表达式类型。
Definition re.h:53
std::match_results< typename string_type::const_iterator > match_type
正则表达式的match_results类型。
Definition re.h:55
std::pair< string_type, int > subn(const string_type &repl, const string_type &text, int count=0) const
Definition re.h:269
regex_type pattern
Definition re.h:68
std::regex_token_iterator< typename string_type::const_iterator, CharT, std::regex_traits< CharT > > token_iterator
词元类型。
Definition re.h:63
Match search(string_type text) const
Definition re.h:175
std::vector< string_type > findall(const string_type &text) const
Definition re.h:208
typename regex_type::flag_type flag_type
标志类型。
Definition re.h:57
std::vector< string_type > split(const string_type &text, int maxsplit=0) const
Definition re.h:223
BasicRegex(const string_type &pat, flag_type flags=regex_type::ECMAScript)
构造函数,初始化正则表达式模式。
Definition re.h:76
std::basic_string< CharT, Traits > string_type
字符串类型。
Definition re.h:51
Match match(string_type text) const
Definition re.h:188
std::regex_iterator< typename string_type::const_iterator, CharT, std::regex_traits< CharT > > iterator_type
迭代器类型。
Definition re.h:59
string_type sub(const string_type &repl, const string_type &text, int count=0) const
Definition re.h:243
提供些许关于迭代器的拓展功能。
Definition re.h:301
std::string escape(const std::string &s)
转义正则表达式中的特殊字符。
Definition re.h:451
std::vector< std::string > findall(const std::string &pattern, const std::string &text)
在文本中查找所有匹配正则表达式的子串。
Definition re.h:375
Regex::Match match(const std::string &pattern, const std::string &text)
在文本中匹配正则表达式的第一个匹配项。
Definition re.h:353
std::string sub(const std::string &pattern, const std::string &repl, const std::string &text, int count=0)
在文本中替换正则表达式匹配的子串。
Definition re.h:424
std::vector< std::string > split(const std::string &pattern, const std::string &text, int maxsplit=0)
在文本中按正则表达式模式分割字符串。
Definition re.h:397
Regex::Match search(const std::string &pattern, const std::string &text)
在文本中搜索正则表达式的第一个匹配项。
Definition re.h:331
Regex compile(const std::string &pattern, std::regex::flag_type flags=std::regex::ECMAScript)
编译字符串模式为正则表达式。
Definition re.h:308
本库所有组件所在的顶层命名空间。
BasicRegex< wchar_t > WRegex
宽字符正则表达式。
Definition re.h:299
BasicRegex< char > Regex
字符正则表达式。
Definition re.h:298
std::ptrdiff_t pos
组的起始位置。
Definition re.h:87
std::ptrdiff_t len
组的长度。
Definition re.h:88