1
0
mirror of https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git synced 2025-07-18 11:19:10 +00:00

Merge pull request #261 from zrax/regex

Add basic regex functionality to plString
This commit is contained in:
Branan Purvine-Riley
2013-01-20 20:56:50 -08:00
7 changed files with 105 additions and 4 deletions

View File

@ -172,10 +172,6 @@ target_link_libraries(plClient ${Vorbis_LIBRARIES})
target_link_libraries(plClient ${DirectX_LIBRARIES})
target_link_libraries(plClient ${CURL_LIBRARY})
if(Bink_SDK_AVAILABLE)
target_link_libraries(plClient ${Bink_LIBRARIES})
endif()
if(USE_VLD)
target_link_libraries(plClient ${VLD_LIBRARY})
endif()

View File

@ -97,6 +97,8 @@ set(CoreLib_HEADERS
)
add_library(CoreLib STATIC ${CoreLib_SOURCES} ${CoreLib_HEADERS})
target_link_libraries(CoreLib ${PCRE_LIBRARY})
if(UNIX)
target_link_libraries(CoreLib pthread)
endif(UNIX)

View File

@ -46,6 +46,8 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include <cstdlib>
#include <wchar.h>
#include <memory>
#include <functional>
#include <pcre.h>
const plString plString::Null;
@ -600,6 +602,70 @@ int plString::Find(const char *str, CaseSensitivity sense) const
}
}
bool plString::REMatch(const char *pattern, CaseSensitivity sense) const
{
int opts = PCRE_UTF8;
if (sense == kCaseInsensitive)
opts |= PCRE_CASELESS;
plString pat_full = plString::Format("(?:%s)\\z", pattern);
const char *errptr;
int erroffs;
std::unique_ptr<pcre, std::function<void (pcre *)>>
re(pcre_compile(pat_full.c_str(), opts, &errptr, &erroffs, nullptr), pcre_free);
if (!re.get()) {
hsAssert(0, plString::Format("Invalid Regex pattern: %s (at %d)", errptr, erroffs).c_str());
return false;
}
int result = pcre_exec(re.get(), nullptr, c_str(), GetSize(), 0,
PCRE_ANCHORED, nullptr, 0);
if (result >= 0)
return true;
hsAssert(result == PCRE_ERROR_NOMATCH, plString::Format("Regex match error: %d", result).c_str());
return false;
}
std::vector<plString> plString::RESearch(const char *pattern,
CaseSensitivity sense) const
{
int opts = PCRE_UTF8;
if (sense == kCaseInsensitive)
opts |= PCRE_CASELESS;
const char *errptr;
int erroffs;
std::unique_ptr<pcre, std::function<void (pcre *)>>
re(pcre_compile(pattern, opts, &errptr, &erroffs, nullptr), pcre_free);
if (!re.get()) {
hsAssert(0, plString::Format("Invalid Regex pattern: %s (at %d)", errptr, erroffs).c_str());
return std::vector<plString>();
}
int ncaps = 0;
pcre_fullinfo(re.get(), nullptr, PCRE_INFO_CAPTURECOUNT, &ncaps);
ncaps += 1; // For the whole-pattern capture
std::unique_ptr<int> outvec(new int[ncaps * 3]);
memset(outvec.get(), -1, sizeof(int) * ncaps * 3);
int result = pcre_exec(re.get(), nullptr, c_str(), GetSize(), 0, 0,
outvec.get(), ncaps * 3);
if (result >= 0) {
std::vector<plString> caps;
caps.resize(ncaps);
for (int i = 0; i < ncaps; ++i) {
int start = outvec.get()[i*2], end = outvec.get()[i*2+1];
if (start >= 0)
caps[i] = Substr(start, end - start);
}
return caps;
}
hsAssert(result == PCRE_ERROR_NOMATCH, plString::Format("Regex search error: %d", result).c_str());
return std::vector<plString>();
}
static bool in_set(char key, const char *charset)
{
for (const char *cs = charset; *cs; ++cs) {

View File

@ -479,6 +479,20 @@ public:
int Find(const plString &str, CaseSensitivity sense = kCaseSensitive) const
{ return Find(str.c_str(), sense); }
/** Check that this string matches the specified regular expression.
* This with only return true if the whole string can be matched
* by \a pattern.
*/
bool REMatch(const char *pattern, CaseSensitivity sense = kCaseSensitive) const;
/** Search for substrings which match the specified regular expression.
* If capture groups are specified in the pattern, they will be
* returned as additional strings in the returned vector, starting at
* index 1 (index 0 contains the whole match). If the pattern was not
* found, this returns an empty vector.
*/
std::vector<plString> RESearch(const char *pattern, CaseSensitivity sense = kCaseSensitive) const;
/** Trim any characters in the supplied \a charset from the left of
* this string.
*/