lua 提取 字符串操作 可以用在c 程序当中 2

来源:互联网 发布:hive从本地导入数据 编辑:程序博客网 时间:2024/06/05 00:39

// 增加了 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;
}

0 0