Does a FullMatchN on the given string and regex and returns a map with pairs as follows: a. For a named group - b. For an unnamed group -
| 104 | // a. For a named group - <named_group_name, captured_string> |
| 105 | // b. For an unnamed group - <group_index, captured_string> |
| 106 | absl::StatusOr<Value> CaptureStringN( |
| 107 | int regex_max_program_size, const StringValue& target, |
| 108 | const StringValue& regex, |
| 109 | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
| 110 | google::protobuf::MessageFactory* absl_nonnull message_factory, |
| 111 | google::protobuf::Arena* absl_nonnull arena) { |
| 112 | std::string target_scratch; |
| 113 | std::string regex_scratch; |
| 114 | absl::string_view target_view = target.ToStringView(&target_scratch); |
| 115 | absl::string_view regex_view = regex.ToStringView(®ex_scratch); |
| 116 | RE2 re2(regex_view, cel::internal::MakeRE2Options()); |
| 117 | CEL_RETURN_IF_ERROR(cel::internal::CheckRE2(re2, regex_max_program_size)) |
| 118 | .With(ErrorValueReturn()); |
| 119 | const int capturing_groups_count = re2.NumberOfCapturingGroups(); |
| 120 | const auto& named_capturing_groups_map = re2.CapturingGroupNames(); |
| 121 | if (capturing_groups_count <= 0) { |
| 122 | return ErrorValue(absl::InvalidArgumentError( |
| 123 | "Capturing groups were not found in the given regex.")); |
| 124 | } |
| 125 | std::vector<std::string> captured_strings(capturing_groups_count); |
| 126 | std::vector<RE2::Arg> captured_string_addresses(capturing_groups_count); |
| 127 | std::vector<RE2::Arg*> argv(capturing_groups_count); |
| 128 | for (int j = 0; j < capturing_groups_count; j++) { |
| 129 | captured_string_addresses[j] = &captured_strings[j]; |
| 130 | argv[j] = &captured_string_addresses[j]; |
| 131 | } |
| 132 | bool result = |
| 133 | RE2::FullMatchN(target_view, re2, argv.data(), capturing_groups_count); |
| 134 | if (!result) { |
| 135 | return ErrorValue(absl::InvalidArgumentError( |
| 136 | "Unable to capture groups for the given regex")); |
| 137 | } |
| 138 | auto builder = cel::NewMapValueBuilder(arena); |
| 139 | builder->Reserve(capturing_groups_count); |
| 140 | for (int index = 1; index <= capturing_groups_count; index++) { |
| 141 | auto it = named_capturing_groups_map.find(index); |
| 142 | std::string name = it != named_capturing_groups_map.end() |
| 143 | ? it->second |
| 144 | : std::to_string(index); |
| 145 | CEL_RETURN_IF_ERROR(builder->Put( |
| 146 | StringValue::From(std::move(name), arena), |
| 147 | StringValue::From(std::move(captured_strings[index - 1]), arena))); |
| 148 | } |
| 149 | return std::move(*builder).Build(); |
| 150 | } |
| 151 | |
| 152 | absl::Status RegisterRegexFunctions(FunctionRegistry& registry, |
| 153 | int max_regex_program_size) { |
nothing calls this directly
no test coverage detected