diff --git a/samples/regex.nut b/samples/regex.nut new file mode 100644 index 0000000..fcd8e59 --- /dev/null +++ b/samples/regex.nut @@ -0,0 +1,10 @@ +local ex = regexp("[a-zA-Z]+"); +local string = "123 Test; strlen(str);"; +local res = ex.search(string); +print(string.slice(res.begin,res.end)); //prints "Test" +print("\n"); +ex = regexp(@"\m()"); +string = "123 Test; doSomething(str, getTemp(), (a+(b/c)));"; +res = ex.search(string); +print(string.slice(res.begin,res.end)); //prints "(...)" +print("\n"); diff --git a/sqstdlib/sqstdrex.cpp b/sqstdlib/sqstdrex.cpp index 2f91792..143516a 100644 --- a/sqstdlib/sqstdrex.cpp +++ b/sqstdlib/sqstdrex.cpp @@ -13,7 +13,7 @@ static const SQChar *g_nnames[] = _SC("NONE"),_SC("OP_GREEDY"), _SC("OP_OR"), _SC("OP_EXPR"),_SC("OP_NOCAPEXPR"),_SC("OP_DOT"), _SC("OP_CLASS"), _SC("OP_CCLASS"),_SC("OP_NCLASS"),_SC("OP_RANGE"),_SC("OP_CHAR"), - _SC("OP_EOL"),_SC("OP_BOL"),_SC("OP_WB") + _SC("OP_EOL"),_SC("OP_BOL"),_SC("OP_WB"),_C("OP_MB") }; #endif @@ -31,6 +31,7 @@ static const SQChar *g_nnames[] = #define OP_EOL (MAX_CHAR+11) #define OP_BOL (MAX_CHAR+12) #define OP_WB (MAX_CHAR+13) +#define OP_MB (MAX_CHAR+14) //match balanced #define SQREX_SYMBOL_ANY_CHAR ('.') #define SQREX_SYMBOL_GREEDY_ONE_OR_MORE ('+') @@ -139,7 +140,20 @@ static SQInteger sqstd_rex_charnode(SQRex *exp,SQBool isclass) t = *exp->_p; exp->_p++; return sqstd_rex_charclass(exp,t); } - case 'b': + case 'm': + { + SQChar cb, ce; //cb = character begin match ce = character end match + cb = *++exp->_p; //skip 'm' + ce = *++exp->_p; + exp->_p++; //points to the next char to be parsed + if ((!cb) || (!ce)) sqstd_rex_error(exp,_SC("balanced chars expected")); + if ( cb == ce ) sqstd_rex_error(exp,_SC("open/close char can't be the same")); + SQInteger node = sqstd_rex_newnode(exp,OP_MB); + exp->_nodes[node].left = cb; + exp->_nodes[node].right = ce; + return node; + } + case 'b': case 'B': if(!isclass) { SQInteger node = sqstd_rex_newnode(exp,OP_WB); @@ -199,8 +213,6 @@ static SQInteger sqstd_rex_class(SQRex *exp) if(first!=-1){ SQInteger c = first; exp->_nodes[chain].next = c; - chain = c; - first = -1; } /* hack? */ exp->_nodes[ret].left = exp->_nodes[ret].next; @@ -506,6 +518,23 @@ static const SQChar *sqstd_rex_matchnode(SQRex* exp,SQRexNode *node,const SQChar return str; } return NULL; + case OP_MB: + { + int cb = node->left; //char that opens a balanced expression + if(*str != cb) return NULL; // string doesnt start with open char + int ce = node->right; //char that closes a balanced expression + int cont = 1; + const SQChar *strEol = exp->_eol; + while (++str < strEol) { + if (*str == ce) { + if (--cont == 0) { + return ++str; + } + } + else if (*str == cb) cont++; + } + } + return NULL; // string ends out of balance default: /* char */ if(*str != node->type) return NULL; str++;