// 增加了 str_find str_gsub 两个函数
// 测试如下
// str_gsub( "yangzm 32zm", "zm", "12" );
// str_find( "yangzm", "zm" );
static const char *lmemfind (const char *s1, size_t l1,
const char *s2, size_t l2){
if (l2 == 0) return s1; /* empty strings are everywhere */
else if (l2 > l1) return NULL; /* avoids a negative `l1' */
else {
const char *init; /* to search for a `*s2' inside `s1' */
l2--; /* 1st char will be checked by `memchr' */
l1 = l1-l2; /* `s2' cannot be found after that */
while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) {
init++; /* 1st char is already checked */
if (memcmp(init, s2+1, l2) == 0)
return init-1;
else { /* correct `l1' and `s1' to try again */
l1 -= init-s1;
s1 = init;
}
}
return NULL; /* not found */
}
}
bool str_find( const char* s, const char* p, int pos = 1 )
{
size_t ls,lp;
ls = strlen( s );
lp = strlen( p );
size_t init = posrelat( pos, ls );
if (init < 1) init = 1;
else if (init > ls + 1) { /* start after string's end? */
//lua_pushnil(L); /* cannot find anything */
return false;
}
const char *s2 = lmemfind(s + init - 1, ls - init + 1, p, lp);
if ( s2 )
{
size_t pa = s2 - s + 1;
size_t pb = s2 - s + lp;
return true;
}
//if (s2) {
//lua_pushinteger(L, s2 - s + 1);
//lua_pushinteger(L, s2 - s + lp);
//return 2;
//}
return false;
}
static void push_onecapture (MatchState *ms, int i, const char *s, const char *e)
{
if (i >= ms->level)
{
if (i == 0) /* ms->level == 0, too */
{
//lua_pushlstring(ms->L, s, e - s); /* add whole match */
}
else
printf("invalid capture index");
}
else
{
ptrdiff_t l = ms->capture[i].len;
if (l == CAP_UNFINISHED)
printf("unfinished capture");
if (l == CAP_POSITION)
{
//lua_pushinteger(ms->L, ms->capture[i].init - ms->src_init + 1);
}
else
{
//lua_pushlstring(ms->L, ms->capture[i].init, l);
}
}
}
std::string str_gsub( const char* src, const char*p, const char* ne, int max_ = 0 )
{
size_t srcl, lp;
srcl = strlen(src);
lp = strlen(p);
int anchor = (*p == '^');
if (anchor) {
p++; lp--;
}
size_t max_s;
if ( max_ == 0 )
max_s = srcl + 1;
else
max_s = max_;
size_t n = 0;
MatchState ms;
ms.matchdepth = MAXCCALLS;
ms.src_init = src;
ms.src_end = src+srcl;
ms.p_end = p + lp;
std::string strb;
while (n < max_s)
{
const char *e;
ms.level = 0;
//lua_assert(ms.matchdepth == MAXCCALLS);
e = match(&ms, src, p);
if (e) {
n++;
//add_value(&ms, &b, src, e, tr);
size_t l, i;
const char *news = ne;
l = strlen( news );
for (i = 0; i < l; i++) {
if (news[i] != L_ESC)
//luaL_addchar(b, news[i]);
strb += news[i];
else {
i++; /* skip ESC */
if (!isdigit(uchar(news[i]))) {
if (news[i] != L_ESC)
printf("invalid use of in replacement string");
//luaL_addchar(b, news[i]);
strb += news[i];
}
else if (news[i] == '0')
{
std::string str = src;
str = str.substr( e - src, str.size() - ( e-src ) );
strb.append( str );
//luaL_addlstring(b, s, e - s);
}
else {
push_onecapture(&ms, news[i] - '1', src, e);
//luaL_addvalue(b); /* add capture to accumulated result */
}
}
}
}
if (e && e>src)
src = e;
else if (src < ms.src_end)
{
//luaL_addchar(&b, *src++);
strb += *src++;
}
else break;
if (anchor) break;
}
return strb;
}