MCPcopy Create free account
hub / github.com/cel-expr/cel-cpp / ReplaceN

Function ReplaceN

extensions/regex_ext.cc:174–231  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

172}
173
174Value ReplaceN(int regex_max_program_size, const StringValue& target,
175 const StringValue& regex, const StringValue& replacement,
176 int64_t count,
177 const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
178 google::protobuf::MessageFactory* absl_nonnull message_factory,
179 google::protobuf::Arena* absl_nonnull arena) {
180 if (count == 0) {
181 return target;
182 }
183 if (count < 0) {
184 return ReplaceAll(regex_max_program_size, target, regex, replacement,
185 descriptor_pool, message_factory, arena);
186 }
187
188 std::string target_scratch;
189 std::string regex_scratch;
190 std::string replacement_scratch;
191 absl::string_view target_view = target.ToStringView(&target_scratch);
192 absl::string_view regex_view = regex.ToStringView(&regex_scratch);
193 absl::string_view replacement_view =
194 replacement.ToStringView(&replacement_scratch);
195 RE2 re2(regex_view, cel::internal::MakeRE2Options());
196 CEL_RETURN_IF_ERROR(cel::internal::CheckRE2(re2, regex_max_program_size))
197 .With(ErrorValueReturn());
198 std::string error_string;
199 if (!re2.CheckRewriteString(replacement_view, &error_string)) {
200 return ErrorValue(absl::InvalidArgumentError(
201 absl::StrFormat("invalid replacement string: %s", error_string)));
202 }
203
204 std::string output;
205 absl::string_view temp_target = target_view;
206 int replaced_count = 0;
207 // RE2's Rewrite only supports substitutions for groups \0 through \9.
208 absl::string_view match[10];
209 int nmatch = std::min(9, re2.NumberOfCapturingGroups()) + 1;
210
211 while (replaced_count < count &&
212 re2.Match(temp_target, 0, temp_target.length(), RE2::UNANCHORED, match,
213 nmatch)) {
214 absl::string_view full_match = match[0];
215
216 output.append(temp_target.data(), full_match.data() - temp_target.data());
217
218 if (!re2.Rewrite(&output, replacement_view, match, nmatch)) {
219 // This should ideally not happen given CheckRewriteString passed
220 return ErrorValue(absl::InternalError("rewrite failed unexpectedly"));
221 }
222
223 temp_target.remove_prefix(full_match.data() - temp_target.data() +
224 full_match.length());
225 replaced_count++;
226 }
227
228 output.append(temp_target.data(), temp_target.length());
229
230 return StringValue::From(std::move(output), arena);
231}

Callers

nothing calls this directly

Calls 8

ReplaceAllFunction · 0.85
MakeRE2OptionsFunction · 0.85
CheckRE2Function · 0.85
ErrorValueReturnClass · 0.85
ErrorValueFunction · 0.85
ToStringViewMethod · 0.80
WithMethod · 0.80
MatchMethod · 0.80

Tested by

no test coverage detected