예제 #1
0
tb_char_t const* tb_regex_replace_done(tb_char_t const* pattern, tb_size_t mode, tb_char_t const* cstr, tb_size_t size, tb_size_t start, tb_char_t const* replace_cstr, tb_size_t replace_size, tb_size_t* plength)
{
    // clear length first
    if (plength) *plength = 0;

    // init regex
    tb_char_t*      result = tb_null;
    tb_regex_ref_t  regex = tb_regex_init(pattern, mode);
    if (regex)
    {
        // replace regex
        tb_size_t           result_size = 0;
        tb_char_t const*    result_cstr = tb_regex_replace(regex, cstr, size, start, replace_cstr, replace_size, &result_size);
        if (result_cstr && result_size)
        {
            // save result
            result = tb_strndup(result_cstr, result_size);
            if (result)
            {
                // save length
                if (plength) *plength = result_size;
            }
        }

        // exit regex
        tb_regex_exit(regex);
    }

    // ok?
    return result;
}
예제 #2
0
파일: pcre2.c 프로젝트: waruqi/tbox
tb_long_t tb_regex_match(tb_regex_ref_t self, tb_char_t const* cstr, tb_size_t size, tb_size_t start, tb_size_t* plength, tb_vector_ref_t* presults)
{
    // check
    tb_regex_t* regex = (tb_regex_t*)self;
    tb_assert_and_check_return_val(regex && regex->code && regex->match_data && cstr, -1);

    // done
    tb_long_t ok = -1;
    do
    {
        // clear length first
        if (plength) *plength = 0;

        // end?
        tb_check_break(start < size);

        // init options
#ifdef __tb_debug__
        tb_uint32_t options = 0;
#else
        tb_uint32_t options = PCRE2_NO_UTF_CHECK;
#endif

        // match it
        tb_long_t count = pcre2_match(regex->code, (PCRE2_SPTR)cstr, (PCRE2_SIZE)size, (PCRE2_SIZE)start, options, regex->match_data, tb_null);
        if (count < 0)
        {
            // no match?
            tb_check_break(count != PCRE2_ERROR_NOMATCH);

#if defined(__tb_debug__) && !defined(TB_CONFIG_OS_WINDOWS)
            // get error info
            PCRE2_UCHAR info[256];
            pcre2_get_error_message(count, info, sizeof(info));

            // trace
            tb_trace_d("match failed at offset %lu: error: %ld, %s\n", start, count, info);
#endif

            // end
            break;
        }

        // check
        tb_assertf_and_check_break(count, "ovector has not enough space!");

        // get output vector
        PCRE2_SIZE* ovector = pcre2_get_ovector_pointer(regex->match_data);
        tb_assert_and_check_break(ovector);

        // get the match offset and length
        tb_size_t offset = (tb_size_t)ovector[0];
        tb_size_t length = (tb_size_t)ovector[1] - ovector[0];
        tb_assert_and_check_break(offset + length <= size);

        // trace
        tb_trace_d("matched count: %lu, offset: %lu, length: %lu", count, offset, length);

        // save results
        if (presults)
        {
            // init results if not exists
            tb_vector_ref_t results = *presults;
            if (!results)
            {
                // init it
                if (!regex->results) regex->results = tb_vector_init(16, tb_element_mem(sizeof(tb_regex_match_t), tb_regex_match_exit, tb_null));

                // save it
                *presults = results = regex->results;
            }
            tb_assert_and_check_break(results);

            // clear it first
            tb_vector_clear(results);

            // done
            tb_long_t           i = 0;
            tb_regex_match_t    entry;
            for (i = 0; i < count; i++)
            {
                // get substring offset and length
                tb_size_t substr_offset = ovector[i << 1];
                tb_size_t substr_length = ovector[(i << 1) + 1] - ovector[i << 1];
                tb_assert_and_check_break(substr_offset + substr_length <= size);

                // make match entry
                entry.cstr  = tb_strndup(cstr + substr_offset, substr_length);
                entry.size  = substr_length;
                entry.start = substr_offset;
                tb_assert_and_check_break(entry.cstr);
                
                // trace
                tb_trace_d("    matched: [%lu, %lu]: %s", entry.start, entry.size, entry.cstr);

                // append it
                tb_vector_insert_tail(results, &entry);
            }
            tb_assert_and_check_break(i == count);
        }

        // save length 
        if (plength) *plength = length;

        // ok
        ok = offset;

    } while (0);

    // ok?
    return ok;
}