godot/drivers/nrex/regex.cpp
Zher Huei Lee d0ddf150d9 updated the RegEx library nrex to v0.1
After implementing unit testing to nrex I caught and fixed some errors
so it should behave more like Python's RegEx In addition, I've added
version numbering so it should be able to tell if the library needs
updating. Here are a list of changes:

- Fixed zero count quantifiers failing.
- Fixed infinite recursion if quantifying zero length token.
- Fixed `$` (as a string pattern on its own) not matching.
- Fixed look behind rewinding beyond the start of the string.
- Added support for alternative back reference format `\g{1}` similar to
Python. This allows digits to be used immediately after back references.
- Number of capture groups are still limited to 9 by default but can now
be manually set, with option for no limit at all. (Python has no limit)
- Curly bracket quantifiers `{0}` no longer interpreted as a literal
string if previous token is not quantifiable. (Python behaviour)
2015-12-04 21:18:41 +00:00

117 lines
2.5 KiB
C++

/*************************************************/
/* regex.cpp */
/*************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/*************************************************/
/* Source code within this file is: */
/* (c) 2007-2010 Juan Linietsky, Ariel Manzur */
/* All Rights Reserved. */
/*************************************************/
#include "regex.h"
#include "nrex.hpp"
#include "core/os/memory.h"
void RegEx::_bind_methods() {
ObjectTypeDB::bind_method(_MD("compile","pattern", "capture"),&RegEx::compile, DEFVAL(9));
ObjectTypeDB::bind_method(_MD("find","text","start","end"),&RegEx::find, DEFVAL(0), DEFVAL(-1));
ObjectTypeDB::bind_method(_MD("clear"),&RegEx::clear);
ObjectTypeDB::bind_method(_MD("is_valid"),&RegEx::is_valid);
ObjectTypeDB::bind_method(_MD("get_capture_count"),&RegEx::get_capture_count);
ObjectTypeDB::bind_method(_MD("get_capture","capture"),&RegEx::get_capture);
ObjectTypeDB::bind_method(_MD("get_captures"),&RegEx::_bind_get_captures);
};
StringArray RegEx::_bind_get_captures() const {
StringArray ret;
int count = get_capture_count();
for (int i=0; i<count; i++) {
String c = get_capture(i);
ret.push_back(c);
};
return ret;
};
void RegEx::clear() {
text.clear();
captures.clear();
exp.reset();
};
bool RegEx::is_valid() const {
return exp.valid();
};
int RegEx::get_capture_count() const {
ERR_FAIL_COND_V( !exp.valid(), 0 );
return exp.capture_size();
}
String RegEx::get_capture(int capture) const {
ERR_FAIL_COND_V( get_capture_count() <= capture, String() );
return text.substr(captures[capture].start, captures[capture].length);
}
Error RegEx::compile(const String& p_pattern, int capture) {
clear();
exp.compile(p_pattern.c_str(), capture);
ERR_FAIL_COND_V( !exp.valid(), FAILED );
captures.resize(exp.capture_size());
return OK;
};
int RegEx::find(const String& p_text, int p_start, int p_end) const {
ERR_FAIL_COND_V( !exp.valid(), -1 );
ERR_FAIL_COND_V( p_text.length() < p_start, -1 );
ERR_FAIL_COND_V( p_text.length() < p_end, -1 );
bool res = exp.match(p_text.c_str(), &captures[0], p_start, p_end);
if (res) {
text = p_text;
return captures[0].start;
}
text.clear();
return -1;
};
RegEx::RegEx(const String& p_pattern) {
compile(p_pattern);
};
RegEx::RegEx() {
};
RegEx::~RegEx() {
clear();
};