…20 words
Could you just use std::regex?
There you go:
/** A Helper class that encapsulates the regex operations */
class RegexFunctions
{
public:
static Array<StringArray> findSubstringsThatMatchWildcard(const String ®exWildCard, const String &stringToTest)
{
Array<StringArray> matches;
String remainingText = stringToTest;
StringArray m = getFirstMatch(regexWildCard, remainingText);
while (m.size() != 0 && m[0].length() != 0)
{
remainingText = remainingText.fromFirstOccurrenceOf(m[0], false, false);
matches.add(m);
m = getFirstMatch(regexWildCard, remainingText);
}
return matches;
}
/** Searches a string and returns a StringArray with all matches.
* You can specify and index of a capture group (if not, the entire match will be used). */
static StringArray search(const String& wildcard, const String &stringToTest, int indexInMatch=0)
{
try
{
StringArray searchResults;
std::regex includeRegex(wildcard.toStdString());
std::string xAsStd = stringToTest.toStdString();
std::sregex_iterator it(xAsStd.begin(), xAsStd.end(), includeRegex);
std::sregex_iterator it_end;
while (it != it_end)
{
std::smatch result = *it;
StringArray matches;
for (auto x : result)
{
matches.add(String(x));
}
if (indexInMatch < matches.size()) searchResults.add(matches[indexInMatch]);
++it;
}
return searchResults;
}
catch (std::regex_error e)
{
DBG(e.what());
return StringArray();
}
}
/** Returns the first match of the given wildcard in the test string. The first entry will be the whole match, followed by capture groups. */
static StringArray getFirstMatch(const String &wildcard, const String &stringToTest)
{
try
{
std::regex reg(wildcard.toStdString());
std::string s(stringToTest.toStdString());
std::smatch match;
if (std::regex_search(s, match, reg))
{
StringArray sa;
for (auto x:match)
{
sa.add(String(x));
}
return sa;
}
return StringArray();
}
catch (std::regex_error e)
{
jassertfalse;
DBG(e.what());
return StringArray();
}
}
/** Checks if the given string matches the regex wildcard. */
static bool matchesWildcard(const String &wildcard, const String &stringToTest)
{
try
{
std::regex reg(wildcard.toStdString());
return std::regex_search(stringToTest.toStdString(), reg);
}
catch (std::regex_error e)
{
DBG(e.what());
return false;
}
}
};
Yes, Jules, perhaps I could.
Honestly speaking, I don’t like C++ STL, Boost, other 3rd lib, etc… Lot of abbreviation make me very confused. I’ve never used them since I start the journey of JUCE. At least 2 reasons I love JUCE so much is its name way and code style. I feel JUCE nearly everything could do…It’s really a super great C++ lib I’d say.
Oh, except the support and sympathy for non-English programmer, and TextEditor, text render on Windows…etc.
I know you hate people talking about these… sorry.
Anyway, I still hope JUCE add this powerful function: Regular Expression.
Wow, awesome!!
chrisboy2000, Thank you very much!!
I wanted to share a snippet that behaved a little more closely to javascript’s regex.exec() function:
static juce::StringArray searchAndGetMatches(const juce::String& regex, const juce::String& strToSearch)
{
std::regex characters(regex.toStdString());
auto stdString = strToSearch.toStdString();
auto characters_begin = std::sregex_iterator(stdString.begin(),
stdString.end(),
characters);
auto characters_end = std::sregex_iterator();
std::smatch match;
std::regex_search(stdString, match, characters);
juce::StringArray matches;
if(! match.empty() )
{
for( size_t n = 0; n < match.size(); ++n )
{
matches.add( juce::String(match[n]) );
}
}
return matches;
}
If you’re using a javascript-based regex string, you’ll need to eliminate the leading / and closing /g. You’ll also need to double-escape every \ for it to parse correctly.
Here’s an example from the Forge JS framework, to extract data from PEM-formatted public keys:
var rMessage = /\s*-----BEGIN ([A-Z0-9- ]+)-----\r?\n?([\x21-\x7e\s]+?(?:\r?\n\r?\n))?([:A-Za-z0-9+\/=\s]+?)-----END \1-----/g;
this turns into the following juce::String:
"\\s*-----BEGIN ([A-Z0-9- ]+)-----\\r?\\n?([\\x21-\\x7e\\s]+?(?:\\r?\\n\\r?\\n))?([:A-Za-z0-9+\\/=\\s]+?)-----END \\1-----"
