22#include < regex>
33#include < string>
44#include < unordered_map>
5+ #include < vector>
56#include < memory>
7+ #include < cstring>
68
79// A map to store compiled regex objects
810std::unordered_map<int , std::shared_ptr<std::regex>> regex_cache;
@@ -54,32 +56,69 @@ extern "C" {
5456 std::smatch match;
5557 std::string str (text);
5658 if (std::regex_search (str, match, *it->second )) {
57- return match.str ().c_str (); // Return the matched substring
59+ return strdup ( match.str ().c_str () ); // Return the matched substring
5860 }
5961 return nullptr ; // Return nullptr if no match is found
6062 }
6163
64+
6265 // Find all matches of a regex pattern in a string
63- const char * findall_pattern (int id, const char * text) {
66+ extern " C " char * * findall_pattern (int id, const char * text) {
6467 auto it = regex_cache.find (id);
6568 if (it == regex_cache.end ()) {
6669 return nullptr ; // Return nullptr if the ID is not found
6770 }
6871
6972 std::string str (text);
7073 std::smatch match;
71- std::string result ;
74+ std::vector<std:: string> matches ;
7275 std::string::const_iterator searchStart (str.cbegin ());
7376
77+ // Find all matches
7478 while (std::regex_search (searchStart, str.cend (), match, *it->second )) {
75- result += match.str () + " \n " ; // Append each match to the result string
79+ matches. push_back ( match.str ()) ; // Store each match in the vector
7680 searchStart = match.suffix ().first ;
7781 }
7882
79- if (!result.empty ()) {
80- return result.c_str (); // Return all matches as a single string separated by newlines
83+ if (matches.empty ()) {
84+ return nullptr ; // Return nullptr if no matches are found
85+ }
86+
87+ // Allocate an array of char* to hold the matches
88+ char ** result = (char **)malloc ((matches.size () + 1 ) * sizeof (char *));
89+ if (!result) {
90+ return nullptr ; // Return nullptr if memory allocation fails
91+ }
92+
93+ // Copy each match into the array
94+ for (size_t i = 0 ; i < matches.size (); ++i) {
95+ result[i] = strdup (matches[i].c_str ()); // Duplicate the string
96+ if (!result[i]) {
97+ // Free previously allocated memory if strdup fails
98+ for (size_t j = 0 ; j < i; ++j) {
99+ free (result[j]);
100+ }
101+ free (result);
102+ return nullptr ;
103+ }
104+ }
105+
106+ // Null-terminate the array
107+ result[matches.size ()] = nullptr ;
108+
109+ return result;
110+ }
111+
112+ // Function to free the allocated memory for the matches
113+ extern " C" void free_matches (char ** matches) {
114+ if (!matches) {
115+ return ;
116+ }
117+
118+ for (size_t i = 0 ; matches[i] != nullptr ; ++i) {
119+ free (matches[i]); // Free each string
81120 }
82- return nullptr ; // Return nullptr if no matches are found
121+ free (matches) ; // Free the array itself
83122 }
84123
85124 // Substitute all occurrences of a regex pattern in a string
@@ -91,6 +130,6 @@ extern "C" {
91130
92131 std::string str (text);
93132 std::string result = std::regex_replace (str, *it->second , replacement);
94- return result.c_str (); // Return the modified string
133+ return strdup ( result.c_str () ); // Return the modified string
95134 }
96135}
0 commit comments