Console Library 4.7.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 <regex>
34#include <string>
35#include <vector>
36
37namespace console
38{
44 class Regex
45 {
46 private:
47 std::regex pattern;
48
49 public:
55 Regex(const std::string &pat,
56 std::regex::flag_type flags = std::regex::ECMAScript)
57 : pattern(pat, flags) {}
58
64 class Match
65 {
66 private:
67 std::smatch match;
68 bool success;
69
70 public:
72 Match() : success(false) {}
73
75 Match(const std::smatch &m) : match(m), success(true) {}
76
82 std::string group(int n = 0) const
83 {
84 if (!success || n < 0 || n >= int(match.size()))
85 {
86 return "";
87 }
88 return match[n].str();
89 }
90
95 std::vector<std::string> groups() const
96 {
97 std::vector<std::string> result;
98 if (!success)
99 return result;
100 for (size_t i = 1; i < match.size(); ++i)
101 {
102 result.push_back(match[i].str());
103 }
104 return result;
105 }
106
112 int start(int n = 0) const
113 {
114 if (!success || n < 0 || n >= int(match.size()))
115 {
116 return -1;
117 }
118 return match.position(n);
119 }
120
126 int end(int n = 0) const
127 {
128 if (!success || n < 0 || n >= int(match.size()))
129 {
130 return -1;
131 }
132 return match.position(n) + match.length(n);
133 }
134
140 std::pair<int, int> span(int n = 0) const
141 {
142 return {start(n), end(n)};
143 }
144
149 explicit operator bool() const { return success; }
150 };
151
157 Match search(const std::string &text) const
158 {
159 std::smatch match;
160 if (std::regex_search(text, match, pattern))
161 {
162 return Match(match);
163 }
164 return Match();
165 }
166
172 Match match(const std::string &text) const
173 {
174 std::smatch match;
175 if (std::regex_match(text, match, pattern))
176 {
177 return Match(match);
178 }
179 return Match();
180 }
181
187 Match fullmatch(const std::string &text) const
188 {
189 return match(text);
190 }
191
197 std::vector<std::string> findall(const std::string &text) const
198 {
199 std::vector<std::string> result;
200 auto begin = std::sregex_iterator(
201 text.begin(), text.end(), pattern);
202 auto end = std::sregex_iterator();
203
204 for (auto it = begin; it != end; ++it)
205 {
206 result.push_back(it->str());
207 }
208 return result;
209 }
210
216 {
217 private:
218 std::sregex_iterator it;
219
220 public:
221 Iterator(std::sregex_iterator i) : it(i) {}
222
223 bool operator==(const Iterator &other) const { return it == other.it; }
224 bool operator!=(const Iterator &other) const { return it != other.it; }
225 void operator++() { ++it; }
226 Match operator*() const { return Match(*it); }
227 };
228
234 {
235 private:
236 Iterator begin_;
237 Iterator end_;
238
239 public:
241 IteratorPair(iterator beg, iterator end) : begin_(beg), end_(end) {}
242 iterator begin() const { return begin_; }
243 iterator end() const { return end_; }
244 };
245
251 IteratorPair finditer(const std::string &text) const
252 {
253 return {{std::sregex_iterator(text.begin(), text.end(), pattern)},
254 {std::sregex_iterator()}};
255 }
256
263 std::vector<std::string> split(const std::string &text,
264 int maxsplit = 0) const
265 {
266 std::vector<std::string> result;
267 std::sregex_token_iterator it(text.begin(), text.end(), pattern, -1);
268 std::sregex_token_iterator end;
269
270 int count = 0;
271 for (; it != end && (maxsplit <= 0 || count < maxsplit);
272 ++it, ++count)
273 {
274 result.push_back(*it);
275 }
276
277 if (maxsplit > 0 && count == maxsplit && it != end)
278 {
279 std::string remaining;
280 for (; it != end; ++it)
281 {
282 if (!remaining.empty())
283 remaining += *it;
284 else
285 remaining = *it;
286 }
287 result.push_back(remaining);
288 }
289
290 return result;
291 }
292
300 std::string sub(const std::string &repl,
301 const std::string &text, int count = 0) const
302 {
303 if (count <= 0)
304 {
305 return std::regex_replace(text, pattern, repl);
306 }
307
308 std::string result;
309 auto begin = std::sregex_iterator(
310 text.begin(), text.end(), pattern);
311 auto end = std::sregex_iterator();
312 auto last = text.begin();
313 int replaced = 0;
314
315 for (auto it = begin;
316 it != end && replaced < count;
317 ++it, ++replaced)
318 {
319 result.append(last, text.begin() + it->position());
320 result.append(repl);
321 last = text.begin() + it->position() + it->length();
322 }
323 result.append(last, text.end());
324
325 return result;
326 }
327
335 std::pair<std::string, int> subn(const std::string &repl,
336 const std::string &text,
337 int count = 0) const
338 {
339 if (count <= 0)
340 {
341 auto result = std::regex_replace(text, pattern, repl);
342 auto begin = std::sregex_iterator(
343 text.begin(), text.end(), pattern);
344 auto end = std::sregex_iterator();
345 int cnt = std::distance(begin, end);
346 return {result, cnt};
347 }
348
349 std::string result;
350 auto begin = std::sregex_iterator(
351 text.begin(), text.end(), pattern);
352 auto end = std::sregex_iterator();
353 auto last = text.begin();
354 int replaced = 0;
355
356 for (auto it = begin;
357 it != end && replaced < count;
358 ++it, ++replaced)
359 {
360 result.append(last, text.begin() + it->position());
361 result.append(repl);
362 last = text.begin() + it->position() + it->length();
363 }
364 result.append(last, text.end());
365
366 return {result, replaced};
367 }
368 };
369
374 namespace re
375 {
382 inline Regex compile(const std::string &pattern,
383 std::regex::flag_type flags = std::regex::ECMAScript)
384 {
385 return Regex(pattern, flags);
386 }
387
394 inline Regex::Match search(const std::string &pattern,
395 const std::string &text)
396 {
397 return Regex(pattern).search(text);
398 }
399
406 inline Regex::Match match(const std::string &pattern,
407 const std::string &text)
408 {
409 return Regex(pattern).match(text);
410 }
411
418 inline std::vector<std::string> findall(const std::string &pattern,
419 const std::string &text)
420 {
421 return Regex(pattern).findall(text);
422 }
423
431 inline std::vector<std::string> split(const std::string &pattern,
432 const std::string &text,
433 int maxsplit = 0)
434 {
435 return Regex(pattern).split(text, maxsplit);
436 }
437
446 inline std::string sub(const std::string &pattern,
447 const std::string &repl,
448 const std::string &text, int count = 0)
449 {
450 return Regex(pattern).sub(repl, text, count);
451 }
452
458 inline std::string escape(const std::string &s)
459 {
460 static std::regex special(R"([.^$*+?()\‍[\‍]{}|\\‍])");
461 return std::regex_replace(s, special, R"(\$&)");
462 }
463 }
464}
迭代器,用于遍历所有匹配。
Definition re.h:216
Iterator(std::sregex_iterator i)
Definition re.h:221
bool operator!=(const Iterator &other) const
Definition re.h:224
bool operator==(const Iterator &other) const
Definition re.h:223
void operator++()
Definition re.h:225
Match operator*() const
Definition re.h:226
包装起始和结束迭代器,支持范围 for 循环。
Definition re.h:234
IteratorPair(iterator beg, iterator end)
Definition re.h:241
iterator begin() const
Definition re.h:242
iterator end() const
Definition re.h:243
Iterator iterator
Definition re.h:240
匹配结果对象,包含匹配信息。
Definition re.h:65
int start(int n=0) const
获取指定捕获组在原始字符串中的起始索引。
Definition re.h:112
Match()
默认构造,表示不成功的匹配。
Definition re.h:72
int end(int n=0) const
获取指定捕获组在原始字符串中的结束索引(最后一个字符之后的位置)。
Definition re.h:126
std::vector< std::string > groups() const
获取所有捕获组(不包括整个匹配)的内容。
Definition re.h:95
std::pair< int, int > span(int n=0) const
获取指定捕获组的起始和结束索引组成的 pair。
Definition re.h:140
Match(const std::smatch &m)
从 std::smatch 构造。
Definition re.h:75
std::string group(int n=0) const
获取指定捕获组的内容。
Definition re.h:82
正则表达式对象,封装编译后的模式,提供匹配、搜索、替换等功能。
Definition re.h:45
Match search(const std::string &text) const
在文本中搜索第一个匹配。
Definition re.h:157
std::pair< std::string, int > subn(const std::string &repl, const std::string &text, int count=0) const
替换匹配的子串并返回替换次数。
Definition re.h:335
std::vector< std::string > findall(const std::string &text) const
查找所有不重叠的匹配,返回匹配字符串列表。
Definition re.h:197
Regex(const std::string &pat, std::regex::flag_type flags=std::regex::ECMAScript)
构造一个 Regex 对象。
Definition re.h:55
Match fullmatch(const std::string &text) const
match 的别名,与 Python 的 re.fullmatch 语义相同。
Definition re.h:187
std::vector< std::string > split(const std::string &text, int maxsplit=0) const
使用正则表达式分割字符串。
Definition re.h:263
Match match(const std::string &text) const
尝试从文本开头匹配整个模式。
Definition re.h:172
std::string sub(const std::string &repl, const std::string &text, int count=0) const
替换匹配的子串(最多 count 次)。
Definition re.h:300
IteratorPair finditer(const std::string &text) const
返回一个可迭代对象,遍历所有匹配的 Match 对象。
Definition re.h:251
std::string escape(const std::string &s)
转义正则表达式中的特殊字符。
Definition re.h:458
std::vector< std::string > findall(const std::string &pattern, const std::string &text)
查找所有匹配的字符串(函数式接口)。
Definition re.h:418
Regex::Match match(const std::string &pattern, const std::string &text)
从开头匹配(函数式接口)。
Definition re.h:406
std::string sub(const std::string &pattern, const std::string &repl, const std::string &text, int count=0)
替换匹配的子串(函数式接口)。
Definition re.h:446
std::vector< std::string > split(const std::string &pattern, const std::string &text, int maxsplit=0)
分割字符串(函数式接口)。
Definition re.h:431
Regex::Match search(const std::string &pattern, const std::string &text)
搜索第一个匹配(函数式接口)。
Definition re.h:394
Regex compile(const std::string &pattern, std::regex::flag_type flags=std::regex::ECMAScript)
编译正则表达式并返回 Regex 对象。
Definition re.h:382
本库所有组件所在的顶层命名空间。
函数式正则表达式接口,模仿 Python 的 re 模块。