47 pcre2_code *prcode =
nullptr;
52 pcre2_compile_context *
const ccontext = pcre2compilecontext();
53 size_t erroroffset = -1;
54 prcode = pcre2_compile ((
const uint8_t*) pattern.
c_str(), PCRE2_ZERO_TERMINATED, flags_to_pcre2_compile_options (flags), &errorcode, &erroroffset, ccontext);
56 log (
"Re: failed to compile regex, error=%d: %s", errorcode, pattern);
60 pcre2_code_free (prcode);
65 pcre2_match_data *md = pcre2_match_data_create_from_pattern (prcode,
nullptr);
68 const int ret = pcre2_match (prcode, (
const uint8_t*) input.
c_str(), PCRE2_ZERO_TERMINATED, 0 , MATCH_OPTIONS, md,
nullptr);
71 const uint32_t ovecs = pcre2_get_ovector_count (md);
73 const size_t *ovector = pcre2_get_ovector_pointer (md);
77 pcre2_match_data_free (md); md =
nullptr;
81 grep (
const String &input,
int group)
83 pcre2_match_data *md = pcre2_match_data_create_from_pattern (prcode,
nullptr);
86 const int ret = pcre2_match (prcode, (
const uint8_t*) input.
c_str(), PCRE2_ZERO_TERMINATED, 0 , MATCH_OPTIONS, md,
nullptr);
89 const uint32_t ovecs = pcre2_get_ovector_count (md);
91 group =
uint (-group) < ovecs ?
uint (-group) : 0;
93 const size_t *ovector = pcre2_get_ovector_pointer (md);
94 const size_t start = ovector[group*2], end = ovector[group*2+1];
95 result.
assign (&input[0] + start, &input[0] + end);
98 pcre2_match_data_free (md); md =
nullptr;
102 findall (
const String &input_string)
105 pcre2_match_data *md = pcre2_match_data_create_from_pattern (prcode,
nullptr);
109 const size_t input_length =
strlen (input_string.
c_str());
110 int ret = pcre2_match (prcode, input, input_length, 0 , MATCH_OPTIONS, md,
nullptr);
111 size_t *ovector = ret <= 0 ? nullptr : pcre2_get_ovector_pointer (md);
113 if (ret < 1 || ovector[0] > ovector[1]) {
114 errorcode = ret < 0 ? ret : ret == 0 ? PCRE2_ERROR_NOMEMORY : PCRE2_ERROR_BACKSLASH_K_IN_LOOKAROUND;
115 if (ret != PCRE2_ERROR_NOMATCH)
116 log (
"Re: findall matching error, error=%d", errorcode);
117 pcre2_match_data_free (md); md =
nullptr;
120 result.push_back (
std::string (input + ovector[0], input + ovector[1]));
122 pcre2_pattern_info (prcode, PCRE2_INFO_ALLOPTIONS, &bits);
123 const bool UTF8 = bits & PCRE2_UTF;
124 pcre2_pattern_info (prcode, PCRE2_INFO_NEWLINE, &bits);
125 const bool CRLF_IS_NEWLINE = bits == PCRE2_NEWLINE_ANY || bits == PCRE2_NEWLINE_CRLF || bits == PCRE2_NEWLINE_ANYCRLF;
128 PCRE2_SIZE start_offset = ovector[1];
130 if (ovector[0] == ovector[1]) {
131 if (ovector[0] == input_length)
133 options = PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED;
136 const auto startchar = pcre2_get_startchar (md);
137 if (start_offset <= startchar) {
138 if (startchar >= input_length)
140 start_offset = startchar + 1;
141 for (; UTF8 && start_offset < input_length; start_offset++)
142 if ((input[start_offset] & 0xc0) != 0x80)
147 ret = pcre2_match (prcode, input, input_length, start_offset, options, md,
nullptr);
149 if (ret == PCRE2_ERROR_NOMATCH) {
152 ovector[1] = start_offset + 1;
153 if (CRLF_IS_NEWLINE &&
154 start_offset < input_length - 1 &&
155 input[start_offset] ==
'\r' &&
156 input[start_offset + 1] ==
'\n')
159 while (ovector[1] < input_length) {
160 if ((input[ovector[1]] & 0xc0) != 0x80)
168 if (ret < 1 || ovector[0] > ovector[1]) {
170 errorcode = ret < 0 ? ret : ret == 0 ? PCRE2_ERROR_NOMEMORY : PCRE2_ERROR_BACKSLASH_K_IN_LOOKAROUND;
171 log (
"Re: findall matching error, error=%d", errorcode);
175 result.push_back (
std::string (input + ovector[0], input + ovector[1]));
177 pcre2_match_data_free (md); md =
nullptr;
183 pcre2_match_data *md = pcre2_match_data_create_from_pattern (prcode,
nullptr);
184 pcre2_match_context *mc = pcre2_match_context_create (
nullptr);
186 PCRE2_SUBSTITUTE_OVERFLOW_LENGTH |
187 PCRE2_SUBSTITUTE_GLOBAL |
192 callout_data.max_substitutions = maxsubst;
193 auto callout_function = [] (pcre2_substitute_callout_block*,
void *callout_data_ptr) ->
int {
194 CalloutData &callout_data = *(CalloutData*) callout_data_ptr;
195 return callout_data.max_substitutions-- >= 1 ? 0 : -1;
197 if (callout_data.max_substitutions <
SSIZE_MAX)
198 pcre2_set_substitute_callout (mc, callout_function, &callout_data);
200 PCRE2_SIZE outlength = result.
size() - 1;
201 int ret = pcre2_substitute (prcode, (
const uint8_t*) input.
c_str(), PCRE2_ZERO_TERMINATED, 0 , MATCH_OPTIONS, md, mc,
203 if (ret == PCRE2_ERROR_NOMEMORY) {
204 result.
resize (outlength + 128);
205 ret = pcre2_substitute (prcode, (
const uint8_t*) input.
c_str(), PCRE2_ZERO_TERMINATED, 0 , MATCH_OPTIONS, md, mc,
209 pcre2_match_data_free (md); md =
nullptr;
210 pcre2_match_context_free (mc); mc =
nullptr;