164 lines
3.3 KiB
C++
164 lines
3.3 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"
|
||
|
|
||
|
extern "C" {
|
||
|
|
||
|
#define _UNICODE
|
||
|
#include "trex.h"
|
||
|
|
||
|
};
|
||
|
|
||
|
void RegEx::_bind_methods() {
|
||
|
|
||
|
ObjectTypeDB::bind_method(_MD("compile","pattern"),&RegEx::compile);
|
||
|
ObjectTypeDB::bind_method(_MD("find","text", "start","end"),&RegEx::_bind_find, DEFVAL(0), DEFVAL(-1));
|
||
|
ObjectTypeDB::bind_method(_MD("get_captures"),&RegEx::_bind_get_captures);
|
||
|
};
|
||
|
|
||
|
Error RegEx::compile(const String& p_pattern) {
|
||
|
|
||
|
clear();
|
||
|
const TRexChar* error;
|
||
|
exp = trex_compile(p_pattern.c_str(), &error);
|
||
|
ERR_FAIL_COND_V(!exp, FAILED);
|
||
|
return OK;
|
||
|
};
|
||
|
|
||
|
|
||
|
int RegEx::_bind_find(const String& p_text, int p_start, int p_end) const {
|
||
|
|
||
|
int start, end;
|
||
|
bool ret = find(p_text, start, end, NULL, p_start, p_end);
|
||
|
|
||
|
return ret?start:-1;
|
||
|
};
|
||
|
|
||
|
bool RegEx::find(const String& p_text, int& p_rstart, int &p_rend, List<String>* p_captures, int p_start, int p_end) const {
|
||
|
|
||
|
ERR_FAIL_COND_V( !exp, false );
|
||
|
text=p_text;
|
||
|
|
||
|
const CharType* str = p_text.c_str();
|
||
|
const CharType* start = str + p_start;
|
||
|
const CharType* end = str + (p_end == -1?p_text.size():p_end);
|
||
|
|
||
|
const CharType* out_begin;
|
||
|
const CharType* out_end;
|
||
|
|
||
|
bool ret = trex_searchrange(exp, start, end, &out_begin, &out_end);
|
||
|
if (ret) {
|
||
|
|
||
|
p_rstart = out_begin - str;
|
||
|
p_rend = out_end - str;
|
||
|
|
||
|
if (p_captures) {
|
||
|
|
||
|
int count = get_capture_count();
|
||
|
for (int i=0; i<count; i++) {
|
||
|
|
||
|
int start, len;
|
||
|
get_capture_limits(i, start, len);
|
||
|
p_captures->push_back(p_text.substr(start, len));
|
||
|
};
|
||
|
};
|
||
|
} else {
|
||
|
|
||
|
p_rstart = -1;
|
||
|
};
|
||
|
|
||
|
return ret;
|
||
|
};
|
||
|
|
||
|
|
||
|
bool RegEx::match(const String& p_text, List<String>* p_captures, int p_start, int p_end) const {
|
||
|
|
||
|
ERR_FAIL_COND_V( !exp, false );
|
||
|
|
||
|
int start, end;
|
||
|
return find(p_text, start, end, p_captures, p_start, p_end);
|
||
|
};
|
||
|
|
||
|
int RegEx::get_capture_count() const {
|
||
|
|
||
|
ERR_FAIL_COND_V( exp == NULL, -1 );
|
||
|
|
||
|
return trex_getsubexpcount(exp);
|
||
|
};
|
||
|
|
||
|
Error RegEx::get_capture_limits(int p_capture, int& p_start, int& p_len) const {
|
||
|
|
||
|
ERR_FAIL_COND_V( exp == NULL, ERR_UNCONFIGURED );
|
||
|
|
||
|
TRexMatch match;
|
||
|
TRexBool res = trex_getsubexp(exp, p_capture, &match);
|
||
|
ERR_FAIL_COND_V( !res, FAILED );
|
||
|
p_start = (int)(match.begin - text.c_str());
|
||
|
p_len = match.len;
|
||
|
|
||
|
return OK;
|
||
|
};
|
||
|
|
||
|
String RegEx::get_capture(int p_idx) const {
|
||
|
|
||
|
ERR_FAIL_COND_V( exp == NULL, "" );
|
||
|
int start, len;
|
||
|
Error ret = get_capture_limits(p_idx, start, len);
|
||
|
ERR_FAIL_COND_V(ret != OK, "");
|
||
|
if (len == 0)
|
||
|
return "";
|
||
|
return text.substr(start, len);
|
||
|
};
|
||
|
|
||
|
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;
|
||
|
};
|
||
|
|
||
|
bool RegEx::is_valid() const {
|
||
|
|
||
|
return exp != NULL;
|
||
|
};
|
||
|
|
||
|
void RegEx::clear() {
|
||
|
|
||
|
if (exp) {
|
||
|
|
||
|
trex_free(exp);
|
||
|
exp = NULL;
|
||
|
};
|
||
|
};
|
||
|
|
||
|
RegEx::RegEx(const String& p_pattern) {
|
||
|
|
||
|
exp = NULL;
|
||
|
compile(p_pattern);
|
||
|
};
|
||
|
|
||
|
RegEx::RegEx() {
|
||
|
|
||
|
exp = NULL;
|
||
|
};
|
||
|
|
||
|
RegEx::~RegEx() {
|
||
|
|
||
|
clear();
|
||
|
};
|