mysql db2正则_DB2中实现正则表达式(4)

#include struct scratchPadMapping {

pcre *re;

pcre_extra *extra;

const char *error;

int errOffset;

int numSubstr;

int *substr;

int currentSubstr;

};

void regexpSubstr(

// input parameters

SQLUDF_VARCHAR *pattern, SQLUDF_CLOB *str,

// output

SQLUDF_INTEGER *pos, SQLUDF_VARCHAR *substr,

// null indicators

SQLUDF_NULLIND *pattern_ind, SQLUDF_NULLIND *str_ind,

SQLUDF_NULLIND *pos_ind, SQLUDF_NULLIND *substr_ind,

SQLUDF_TRAIL_ARGS_ALL) // SQLUDF_SCRAT & SQLUDF_CALLT

{

int rc = 0;

size_t length = 0;

struct scratchPadMapping *scratch = NULL;

// map the buffer of the scratchpad and assume NULL return

scratch = (struct scratchPadMapping *)SQLUDF_SCRAT->data;

*pos_ind = 0;

*substr_ind = 0;

switch (SQLUDF_CALLT) {

case SQLUDF_TF_OPEN:

// initialize data on the scratchpad

scratch->re = NULL;

scratch->extra = NULL;

scratch->error = NULL;

scratch->errOffset = 0;

scratch->numSubstr = 0;

scratch->substr = NULL;

scratch->currentSubstr = 1; // skip the complete match

// compile the pattern (only in the FIRST call

scratch->re = pcre_compile(pattern, 0 /* default options */,

&scratch->error, &scratch->errOffset, NULL);

if (scratch->re == NULL) {

snprintf(SQLUDF_MSGTX, 70, "Regexp compilation failed at "

"offset %d: %s\\n", scratch->errOffset, scratch->error);

strcpy(SQLUDF_STATE, "38900");

rc = -1;

break;

}

// further analyze the pattern (might return NULL)

scratch->extra = pcre_study(scratch->re,

0 /* default options */, &scratch->error);

// determine the number of capturing subpatterns

rc = pcre_fullinfo(scratch->re, scratch->extra,

PCRE_INFO_CAPTURECOUNT, &scratch->numSubstr);

if (rc) {

snprintf(SQLUDF_MSGTX, 70, "Could not retrieve info "

"on pattern. (rc = %d)", rc);

strcpy(SQLUDF_STATE, "38901");

rc = -1;

break;

}

// allocate memory for the substring indices

{

int size = (scratch->numSubstr+1)*3;

scratch->substr = (int *)malloc(size * sizeof(int));

if (!scratch->substr) {

snprintf(SQLUDF_MSGTX, 70, "Could allocate memory for "

"substring indices.");

strcpy(SQLUDF_STATE, "38902");

rc = -1;

break;

}

memset(scratch->substr, 0, size * sizeof(int));

// match the current string

rc = pcre_exec(scratch->re, scratch->extra, str->data,

str->length, 0, 0 /* default options */,

scratch->substr, size);

}

switch (rc) {

case PCRE_ERROR_BADOPTION:

snprintf(SQLUDF_MSGTX, 70, "An unrecognized bit was set "

"in the options argument");

strcpy(SQLUDF_STATE, "38903");

rc = -1;

break;

case PCRE_ERROR_NOMEMORY:

snprintf(SQLUDF_MSGTX, 70, "Not enough memory available.");

strcpy(SQLUDF_STATE, "38904");

rc = -1;

break;

case PCRE_ERROR_NOMATCH:

scratch->currentSubstr = scratch->numSubstr + 1;

rc = 0;

break;

default:

if (rc < 0) {

snprintf(SQLUDF_MSGTX, 70, "A regexp match error "

"occured: %d", rc);

strcpy(SQLUDF_STATE, "38905");

rc = -1;

break;

}

}

break;

case SQLUDF_TF_FETCH:

// skip capturing substrings without a match

while (scratch->currentSubstr <= scratch->numSubstr &&

(scratch->substr[2*scratch->currentSubstr] < 0 ||

scratch->substr[2*scratch->currentSubstr+1] < 0)) {

scratch->currentSubstr++;

}

// no more data to be returned

if (scratch->currentSubstr > scratch->numSubstr) {

strcpy(SQLUDF_STATE, SQL_NODATA_EXCEPTION);

rc = 0;

break;

}

// get the current substring

*pos = scratch->currentSubstr;

length = scratch->substr[2*scratch->currentSubstr+1] -

scratch->substr[2*scratch->currentSubstr];

strncpy(substr, str->data + scratch->substr[2*scratch->currentSubstr],

length);

substr[length] = '\\0';

scratch->currentSubstr++;

}

// cleanup in CLOSE call, or if we encountered an error in

// the OPEN call (DB2 will make a CLOSE call if we encounter

// an error in any FETCH call)

if (SQLUDF_CALLT == SQLUDF_TF_CLOSE ||

(SQLUDF_CALLT == SQLUDF_TF_OPEN && rc < 0)) {

(*pcre_free)(scratch->re);

(*pcre_free)(scratch->extra);

free(scratch->substr);

}

return;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值