# Ngx.re.split implementation

**URL:** <https://www.ruby-forum.com/t/ngx-re-split-implementation/226319>\
**Category:** NGINX\
**Created:** [July 11, 2012, 9:55pm UTC](https://www.ruby-forum.com/t/ngx-re-split-implementation/226319 "2012-07-11T21:55:27Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jader\_Henrique\_da\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/3ec8ea/32.png) [@Jader\_Henrique\_da\_S](https://www.ruby-forum.com/u/Jader_Henrique_da_S)\
**Post date:** [July 11, 2012, 9:55pm UTC](https://www.ruby-forum.com/t/ngx-re-split-implementation/226319/1 "2012-07-11T21:55:27Z")

</div>

Hello

I was checking HttpLuaModule docs and saw “ngx.re.split” implementation  
in the TODO section.

Is it already implemented?  
Are there any details about this implementation (e.g. parameters,  
returned data)?

Jader H. Silva

* * *

AVISO: A informao contida neste e-mail, bem como em qualquer de seus  
anexos, CONFIDENCIAL e destinada ao uso exclusivo do(s) destinatrio(s)  
acima referido(s), podendo conter informaes sigilosas e/ou legalmente  
protegidas. Caso voc no seja o destinatrio desta mensagem, informamos  
que qualquer divulgao, distribuio ou cpia deste e-mail e/ou de qualquer  
de seus anexos absolutamente proibida. Solicitamos que o remetente seja  
comunicado imediatamente, respondendo esta mensagem, e que o original  
desta mensagem e de seus anexos, bem como toda e qualquer cpia e/ou  
impresso realizada a partir destes, sejam permanentemente apagados e/ou  
destrudos. Informaes adicionais sobre nossa empresa podem ser obtidas no  
site [http://sobre.uol.com.br/](http://sobre.uol.com.br/).

NOTICE: The information contained in this e-mail and any attachments  
thereto is CONFIDENTIAL and is intended only for use by the recipient  
named herein and may contain legally privileged and/or secret  
information.  
If you are not the e-mails intended recipient, you are hereby notified  
that any dissemination, distribution or copy of this e-mail, and/or any  
attachments thereto, is strictly prohibited. Please immediately notify  
the sender replying to the above mentioned e-mail address, and  
permanently delete and/or destroy the original and any copy of this  
e-mail and/or its attachments, as well as any printout thereof.  
Additional information about our company may be obtained through the  
site [UOL - Seu universo online](http://www.uol.com.br/ir/).

---

<div class="post-metadata">

**Author:** ![Jader\_Henrique\_da\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/3ec8ea/32.png) [@Jader\_Henrique\_da\_S](https://www.ruby-forum.com/u/Jader_Henrique_da_S)\
**Post date:** [July 11, 2012, 11:21pm UTC](https://www.ruby-forum.com/t/ngx-re-split-implementation/226319/2 "2012-07-11T23:21:56Z")

</div>

Show!! As listas nos ajudam muito.

Só uma recomendacao: procure utilizar o seu email pessoal em listas de  
discussao. Nao utilizamos o corporativo para nao dar indicios do q  
estamos mexendo no UOL.

Abs

Sent from my iPhone

---

<div class="post-metadata">

**Author:** ![Jader\_Henrique\_da\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/3ec8ea/32.png) [@Jader\_Henrique\_da\_S](https://www.ruby-forum.com/u/Jader_Henrique_da_S)\
**Post date:** [July 11, 2012, 11:27pm UTC](https://www.ruby-forum.com/t/ngx-re-split-implementation/226319/3 "2012-07-11T23:27:47Z")

</div>

Sorry… Wrong mail.

---

<div class="post-metadata">

**Author:** ![Jader\_Henrique\_da\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/3ec8ea/32.png) [@Jader\_Henrique\_da\_S](https://www.ruby-forum.com/u/Jader_Henrique_da_S)\
**Post date:** [July 12, 2012, 1:41am UTC](https://www.ruby-forum.com/t/ngx-re-split-implementation/226319/4 "2012-07-12T01:41:10Z")

</div>

Hello!

On Wed, Jul 11, 2012 at 12:54 PM, Jader Henrique da Silva  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I was checking HttpLuaModule docs and saw “ngx.re.split” implementation in  
> the TODO section.
> 
> Is it already implemented?

Nope, otherwise I would update the TODO section accordingly 🙂

> Are there any details about this implementation (e.g. parameters, returned  
> data)?

Not yet. But I think the behavior will be similar to Perl 5’s split  
builtin function.

I’m always open to patches for this feature 🙂

Best regards,  
-agentzh

---

<div class="post-metadata">

**Author:** ![Jader\_Henrique\_da\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/3ec8ea/32.png) [@Jader\_Henrique\_da\_S](https://www.ruby-forum.com/u/Jader_Henrique_da_S)\
**Post date:** [July 13, 2012, 11:13pm UTC](https://www.ruby-forum.com/t/ngx-re-split-implementation/226319/5 "2012-07-13T23:13:42Z")

</div>

So, here it is 🙂

ngx.re.split(_subject, regex, options?_, limit?)

This function is based on ngx\_re\_sub.

It will split subject on regex matches and return a table of strings.  
Limit  
is the max number of splits (0 will return a table containing the  
subject  
string).

Let me know if there are bugs, identation issues or anything I need to  
fix.

Jader H. Silva

2012/7/11 agentzh [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![Jader\_Henrique\_da\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/3ec8ea/32.png) [@Jader\_Henrique\_da\_S](https://www.ruby-forum.com/u/Jader_Henrique_da_S)\
**Post date:** [July 14, 2012, 9:06pm UTC](https://www.ruby-forum.com/t/ngx-re-split-implementation/226319/6 "2012-07-14T21:06:13Z")

</div>

Hello!

On Fri, Jul 13, 2012 at 2:19 PM, Jader H. Silva [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> The patch was removed in the previous message ☹  
> So here it is (for real).

Thanks for the patch! I’ll look into this in the next week 🙂

Best regards,  
-agentzh

---

<div class="post-metadata">

**Author:** ![Jader\_Henrique\_da\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/3ec8ea/32.png) [@Jader\_Henrique\_da\_S](https://www.ruby-forum.com/u/Jader_Henrique_da_S)\
**Post date:** [July 13, 2012, 11:19pm UTC](https://www.ruby-forum.com/t/ngx-re-split-implementation/226319/7 "2012-07-13T23:19:33Z")

</div>

The patch was removed in the previous message ☹  
So here it is (for real).

From 9091c40e22f6fd0ca2173ecbeb1f932502cc8ac6 Mon Sep 17 00:00:00 2001  
From: “Jader H. Silva” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
Date: Fri, 13 Jul 2012 18:06:32 -0300  
Subject: [PATCH] Add ngx.re.split function

* * *

src/ngx\_http\_lua\_regex.c | 443  
++++++++++++++++++++++++++++++++++++++++++++++  
1 file changed, 443 insertions(+)

diff --git a/src/ngx\_http\_lua\_regex.c b/src/ngx\_http\_lua\_regex.c  
index 108070c…aa5d445 100644  
— a/src/ngx\_http\_lua\_regex.c  
+++ b/src/ngx\_http\_lua\_regex.c  
@@ -74,6 +74,7 @@ static int ngx\_http\_lua\_ngx\_re\_match(lua\_State \*L);  
static int ngx\_http\_lua\_ngx\_re\_gmatch(lua\_State \*L);  
static int ngx\_http\_lua\_ngx\_re\_sub(lua\_State \*L);  
static int ngx\_http\_lua\_ngx\_re\_gsub(lua\_State \*L);  
+static int ngx\_http\_lua\_ngx\_re\_split(lua\_State \*L);  
static void ngx\_http\_lua\_regex\_free\_study\_data(ngx\_pool\_t \*pool,  
pcre\_extra \*sd);  
static ngx\_int\_t ngx\_lua\_regex\_compile(ngx\_lua\_regex\_compile\_t \*rc);  
@@ -1611,6 +1612,445 @@ error:  
return luaL\_error(L, msg);  
}

+static int  
+ngx\_http\_lua\_ngx\_re\_split(lua\_State \*L)  
+{

- ngx\_http\_lua\_regex\_t \*re;
- ngx\_http\_request\_t \*r;
- ngx\_str\_t subj;
- ngx\_str\_t pat;
- ngx\_str\_t opts;
- ngx\_str\_t tpl;
- ngx\_http\_lua\_main\_conf\_t \*lmcf = NULL;
- ngx\_pool\_t \*pool, \*old\_pool;
- ngx\_lua\_regex\_compile\_t re\_comp;
- const char \*msg;
- ngx\_int\_t rc;
- ngx\_uint\_t n;
- ngx\_int\_t i;
- int nargs;
- int \*cap = NULL;
- int ovecsize;
- int type;
- unsigned func;
- int offset;
- size\_t count;
- luaL\_Buffer luabuf;
- ngx\_int\_t flags;
- ngx\_int\_t limit = -1;
- u\_char \*p;
- u\_char errstr[NGX\_MAX\_CONF\_ERRSTR + 1];
- pcre\_extra \*sd = NULL;
- 
- ngx\_http\_lua\_complex\_value\_t \*ctpl = NULL;
- ngx\_http\_lua\_compile\_complex\_value\_t ccv;
- 
- nargs = lua\_gettop(L);
- 
- if (nargs != 2 && nargs != 3 && nargs != 4) {
- 

```
   return luaL_error(L, "expecting two or three or four arguments,

```

but got %d",

- 

```
           nargs);

```

- }
- 
- lua\_pushlightuserdata(L, &ngx\_http\_lua\_request\_key);
- lua\_rawget(L, LUA\_GLOBALSINDEX);
- r = lua\_touserdata(L, -1);
- lua\_pop(L, 1);
- 
- if (r == NULL) {
- 

```
   return luaL_error(L, "no request object found");

```

- }
- 
- subj.data = (u\_char \*) luaL\_checklstring(L, 1, &subj.len);
- pat.data = (u\_char \*) luaL\_checklstring(L, 2, &pat.len);
- 
- if (nargs \>= 3) {
- 

```
   opts.data = (u_char *) luaL_checklstring(L, 3, &opts.len);

```

- 
- 

```
   if (nargs == 4) {

```

- 

```
       limit = luaL_checkinteger(L, 4);

```

- 

```
       lua_pop(L, 1);

```

- 
- 

```
   } else {/* nargs == 3 */

```

- 

```
       limit = -1;

```

- 

```
   }

```

- 
- } else { /\* nargs == 2 \*/
- 

```
   opts.data = (u_char *) "";

```

- 

```
   opts.len = 0;

```

- }
- 
- ngx\_memzero(&re\_comp, sizeof(ngx\_lua\_regex\_compile\_t));
- 
- /\* stack: subj regex repl \*/
- 
- re\_comp.options = 0;
- 
- flags = ngx\_http\_lua\_ngx\_re\_parse\_opts(L, &re\_comp, &opts, 4);
- 
- if (flags & NGX\_LUA\_RE\_COMPILE\_ONCE) {
- 

```
   lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module);

```

- 

```
   pool = lmcf->pool;

```

- 
- 

```
   dd("server pool %p", lmcf->pool);

```

- 
- 

```
   lua_pushlightuserdata(L, &ngx_http_lua_regex_cache_key);

```

- 

```
   lua_rawget(L, LUA_REGISTRYINDEX); /* table */

```

- 
- 

```
   lua_pushliteral(L, "s");

```

- 

```
   lua_pushinteger(L, tpl.len);

```

- 

```
   lua_pushliteral(L, ":");

```

- 

```
   lua_pushvalue(L, 2);

```

- 
- 

```
   if (tpl.len != 0) {

```

- 

```
       lua_pushvalue(L, 3);

```

- 

```
   }

```

- 
- 

```
   dd("options size: %d", (int) sizeof(re_comp.options));

```

- 
- 

```
   lua_pushlstring(L, (char *) &re_comp.options,

```

sizeof(re\_comp.options));

- 

```
           /* table regex opts */

```

- 
- 

```
   if (tpl.len == 0) {

```

- 

```
       lua_concat(L, 5); /* table key */

```

- 
- 

```
   } else {

```

- 

```
       lua_concat(L, 6); /* table key */

```

- 

```
   }

```

- 
- 

```
   lua_pushvalue(L, -1); /* table key key */

```

- 
- 

```
   dd("regex cache key: %.*s", (int) (pat.len +

```

sizeof(re\_comp.options)),

- 

```
           lua_tostring(L, -1));

```

- 
- 

```
   lua_rawget(L, -3); /* table key re */

```

- 

```
   re = lua_touserdata(L, -1);

```

- 
- 

```
   lua_pop(L, 1); /* table key */

```

- 
- 

```
   if (re) {

```

- 

```
       ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,

```

- 

```
               "lua regex cache hit for split regex \"%s\" with

```

options "

- 

```
               "\"%s\"", pat.data, opts.data);

```

- 
- 

```
       lua_pop(L, 2);

```

- 
- 

```
       dd("restoring regex %p, ncaptures %d, captures %p", 

```

re-\>regex,

- 

```
               re->ncaptures, re->captures);

```

- 
- 

```
       re_comp.regex = re->regex;

```

- 

```
       sd = re->regex_sd;

```

- 

```
       re_comp.captures = re->ncaptures;

```

- 

```
       cap = re->captures;

```

- 

```
       ctpl = re->replace;

```

- 
- 

```
       if (flags & NGX_LUA_RE_MODE_DFA) {

```

- 

```
           ovecsize = 2;

```

- 
- 

```
       } else {

```

- 

```
           ovecsize = (re->ncaptures + 1) * 3;

```

- 

```
       }

```

- 
- 

```
       goto exec;

```

- 

```
   }

```

- 
- 

```
   ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,

```

- 

```
           "lua regex cache miss for split regex \"%s\" with 

```

options "

- 

```
           "\"%s\"",

```

- 

```
           pat.data, opts.data);

```

- 
- 

```
   if (lmcf->regex_cache_entries >= lmcf->regex_cache_max_entries) 

```

{  
+

- 

```
       if (lmcf->regex_cache_entries ==

```

lmcf-\>regex\_cache\_max\_entries) {

- 

```
           ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,

```

- 

```
                   "lua exceeding regex cache max entries (%i)",

```

- 

```
                   lmcf->regex_cache_max_entries);

```

- 
- 

```
           lmcf->regex_cache_entries++;

```

- 

```
       }

```

- 
- 

```
       pool = r->pool;

```

- 

```
       flags &= ~NGX_LUA_RE_COMPILE_ONCE;

```

- 

```
   }

```

- 
- } else {
- 

```
   pool = r->pool;

```

- }
- 
- re\_comp.pattern = pat;
- re\_comp.err.len = NGX\_MAX\_CONF\_ERRSTR;
- re\_comp.err.data = errstr;
- re\_comp.pool = pool;
- 
- dd(“compiling regex”);
- 
- ngx\_log\_debug5(NGX\_LOG\_DEBUG\_HTTP, r-\>connection-\>log, 0,
- 

```
       "lua compiling split regex \"%s\" with options \"%s\" "

```

- 

```
       "(compile once: %d) (dfa mode: %d) (jit mode: %d)",

```

- 

```
       pat.data, opts.data,

```

- 

```
       (flags & NGX_LUA_RE_COMPILE_ONCE) != 0,

```

- 

```
       (flags & NGX_LUA_RE_MODE_DFA) != 0,

```

- 

```
       (flags & NGX_LUA_RE_MODE_JIT) != 0);

```

- 
- old\_pool = ngx\_http\_lua\_pcre\_malloc\_init(pool);
- 
- rc = ngx\_lua\_regex\_compile(&re\_comp);
- 
- ngx\_http\_lua\_pcre\_malloc\_done(old\_pool);
- 
- if (rc != NGX\_OK) {
- 

```
   dd("compile failed");

```

- 
- 

```
   re_comp.err.data[re_comp.err.len] = '\0';

```

- 

```
   msg = lua_pushfstring(L, "failed to compile regex \"%s\": %s",

```

- 

```
           pat.data, re_comp.err.data);

```

- 
- 

```
   return luaL_argerror(L, 2, msg);

```

- }
- 

+#if LUA\_HAVE\_PCRE\_JIT  
+

- if (flags & NGX\_LUA\_RE\_MODE\_JIT) {
- 
- 

```
   old_pool = ngx_http_lua_pcre_malloc_init(pool);

```

- 
- 

```
   sd = pcre_study(re_comp.regex, PCRE_STUDY_JIT_COMPILE, &msg);

```

- 
- 

```
   ngx_http_lua_pcre_malloc_done(old_pool);

```

- 

+# if (NGX\_DEBUG)

- 

```
   dd("sd = %p", sd);

```

- 
- 

```
   if (msg != NULL) {

```

- 

```
       ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,

```

- 

```
           "pcre study failed with PCRE_STUDY_JIT_COMPILE: %s 

```

(%p)",

- 

```
           msg, sd);

```

- 

```
   }

```

- 
- 

```
   if (sd != NULL) {

```

- 

```
       int jitted;

```

- 
- 

```
       old_pool = ngx_http_lua_pcre_malloc_init(pool);

```

- 
- 

```
       pcre_fullinfo(re_comp.regex, sd, PCRE_INFO_JIT, &jitted);

```

- 
- 

```
       ngx_http_lua_pcre_malloc_done(old_pool);

```

- 
- 

```
       ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,

```

- 

```
           "pcre JIT compiling result: %d", jitted);

```

- 

```
   }

```

+# endif /\* NGX\_DEBUG \*/  
+

- } else {
- 
- 

```
   old_pool = ngx_http_lua_pcre_malloc_init(pool);

```

- 
- 

```
   sd = pcre_study(re_comp.regex, 0, &msg);

```

- 
- 

```
   ngx_http_lua_pcre_malloc_done(old_pool);

```

- 

+# if (NGX\_DEBUG)

- 

```
   dd("sd = %p", sd);

```

- 
- 

```
   if (msg != NULL) {

```

- 

```
       ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,

```

- 

```
           "pcre_study failed with PCRE_STUDY_JIT_COMPILE: %s 

```

(%p)",

- 

```
           msg, sd);

```

- 

```
   }

```

+# endif /\* NGX\_DEBUG \*/

- }
- 

+#else /\* LUA\_HAVE\_PCRE\_JIT \*/  
+

- if (flags & NGX\_LUA\_RE\_MODE\_JIT) {
- 

```
   ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,

```

- 

```
           "your pcre build does not have JIT support and "

```

- 

```
           "the \"j\" regex option is ignored");

```

- }
- 

+#endif /\* LUA\_HAVE\_PCRE\_JIT \*/  
+

- dd(“compile done, captures %d”, re\_comp.captures);
- 
- if (flags & NGX\_LUA\_RE\_MODE\_DFA) {
- 

```
   ovecsize = 2;

```

- 
- } else {
- 

```
   ovecsize = (re_comp.captures + 1) * 3;

```

- }
- 
- cap = ngx\_palloc(pool, ovecsize \* sizeof(int));
- if (cap == NULL) {
- 

```
   flags &= ~NGX_LUA_RE_COMPILE_ONCE;

```

- 

```
   msg = "out of memory";

```

- 

```
   goto error;

```

- }
- 
- if (flags & NGX\_LUA\_RE\_COMPILE\_ONCE) {
- 
- 

```
   ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,

```

- 

```
           "lua saving compiled sub regex (%d captures) into the

```

cache "

- 

```
           "(entries %i)", re_comp.captures,

```

- 

```
           lmcf ? lmcf->regex_cache_entries : 0);

```

- 
- 

```
   re = ngx_palloc(pool, sizeof(ngx_http_lua_regex_t));

```

- 

```
   if (re == NULL) {

```

- 

```
       return luaL_error(L, "out of memory");

```

- 

```
   }

```

- 
- 

```
   dd("saving regex %p, ncaptures %d, captures %p", 

```

re\_comp.regex,

- 

```
           re_comp.captures, cap);

```

- 
- 

```
   re->regex = re_comp.regex;

```

- 

```
   re->regex_sd = sd;

```

- 

```
   re->ncaptures = re_comp.captures;

```

- 

```
   re->captures = cap;

```

- 

```
   re->replace = ctpl;

```

- 
- 

```
   lua_pushlightuserdata(L, re); /* table key value */

```

- 

```
   lua_rawset(L, -3); /* table */

```

- 

```
   lua_pop(L, 1);

```

- 
- 

```
   if (lmcf) {

```

- 

```
       lmcf->regex_cache_entries++;

```

- 

```
   }

```

- }
- 

+exec:

- count = 0;
- offset = 0;
- 
- lua\_newtable(L);
- 
- for (;😉 {
- 

```
   if (subj.len == 0 || count == limit) {

```

- 

```
       break;

```

- 

```
   }

```

- 
- 

```
   if (flags & NGX_LUA_RE_MODE_DFA) {

```

- 

+#if LUA\_HAVE\_PCRE\_DFA  
+

- 

```
       int ws[NGX_LUA_RE_DFA_MODE_WORKSPACE_COUNT];

```

- 

```
       rc = ngx_http_lua_regex_dfa_exec(re_comp.regex, sd, &subj,

```

- 

```
           offset, cap, ovecsize, ws,

```

NGX\_LUA\_RE\_DFA\_MODE\_WORKSPACE\_COUNT);  
+  
+#else /\* LUA\_HAVE\_PCRE\_DFA \*/  
+

- 

```
       msg = "at least pcre 6.0 is required for the DFA mode";

```

- 

```
       goto error;

```

- 

+#endif /\* LUA\_HAVE\_PCRE\_DFA \*/  
+

- 

```
   } else {

```

- 

```
       rc = ngx_http_lua_regex_exec(re_comp.regex, sd, &subj, 

```

offset,  
cap,

- 

```
               ovecsize);

```

- 

```
   }

```

- 
- 

```
   if (rc == NGX_REGEX_NO_MATCHED) {

```

- 

```
       break;

```

- 

```
   }

```

- 
- 

```
   if (rc < 0) {

```

- 

```
       msg = lua_pushfstring(L, ngx_regex_exec_n " failed: %d on

```

"%s" "

- 

```
           "using \"%s\"", (int) rc, subj.data, pat.data);

```

- 

```
       goto error;

```

- 

```
   }

```

- 
- 

```
   if (rc == 0) {

```

- 

```
       if (flags & NGX_LUA_RE_MODE_DFA) {

```

- 

```
           rc = 1;

```

- 
- 

```
       } else {

```

- 

```
           msg = "capture size too small";

```

- 

```
           goto error;

```

- 

```
       }

```

- 

```
   }

```

- 
- 

```
   dd("rc = %d", (int) rc);

```

- 
- 

```
   count++;

```

- 
- 

```
   luaL_buffinit(L, &luabuf);

```

- 
- 

```
   luaL_addlstring(&luabuf, (char *) &subj.data[offset],

```

- 

```
               cap[0] - offset);

```

- 
- 

```
   lua_pushnumber(L, count);

```

- 

```
   luaL_pushresult(&luabuf);

```

- 

```
   lua_settable(L, -3);

```

- 
- 

```
   offset = cap[1];

```

- 
- }
- 
- if (count == 0) {
- 

```
   dd("no match, just the original subject");

```

- 
- 

```
   lua_pushnumber(L, count+1);

```

- 

```
   lua_pushvalue(L, 1);

```

- 

```
   lua_settable(L, -3);

```

- 
- } else {
- 

```
   if (offset != (int) subj.len) {

```

- 

```
       dd("adding trailer: %s (len %d)", &subj.data[offset],

```

- 

```
               (int) (subj.len - offset));

```

- 
- 

```
       luaL_buffinit(L, &luabuf);

```

- 
- 

```
       luaL_addlstring(&luabuf, (char *) &subj.data[offset],

```

- 

```
               subj.len - offset);

```

- 
- 

```
       lua_pushnumber(L, count+1);

```

- 

```
       luaL_pushresult(&luabuf);

```

- 

```
       lua_settable(L, -3);

```

- 
- 

```
   }

```

- 
- 

```
   dd("the dst string: %s", lua_tostring(L, -1));

```

- }
- 
- if (!(flags & NGX\_LUA\_RE\_COMPILE\_ONCE)) {
- 

```
   if (sd) {

```

- 

```
       ngx_http_lua_regex_free_study_data(pool, sd);

```

- 

```
   }

```

- 
- 

```
   if (re_comp.regex) {

```

- 

```
       ngx_pfree(pool, re_comp.regex);

```

- 

```
   }

```

- 
- 

```
   if (ctpl) {

```

- 

```
       ngx_pfree(pool, ctpl);

```

- 

```
   }

```

- 
- 

```
   if (cap) {

```

- 

```
       ngx_pfree(pool, cap);

```

- 

```
   }

```

- }
- 
- return 1;
- 

+error:

- if (!(flags & NGX\_LUA\_RE\_COMPILE\_ONCE)) {
- 

```
   if (sd) {

```

- 

```
       ngx_http_lua_regex_free_study_data(pool, sd);

```

- 

```
   }

```

- 
- 

```
   if (re_comp.regex) {

```

- 

```
       ngx_pfree(pool, re_comp.regex);

```

- 

```
   }

```

- 
- 

```
   if (ctpl) {

```

- 

```
       ngx_pfree(pool, ctpl);

```

- 

```
   }

```

- 
- 

```
   if (cap) {

```

- 

```
       ngx_pfree(pool, cap);

```

- 

```
   }

```

- }
- 
- return luaL\_error(L, msg);  
+}

void  
ngx\_http\_lua\_inject\_regex\_api(lua\_State \*L)  
@@ -1631,6 +2071,9 @@ ngx\_http\_lua\_inject\_regex\_api(lua\_State \*L)  
lua\_pushcfunction(L, ngx\_http\_lua\_ngx\_re\_gsub);  
lua\_setfield(L, -2, “gsub”);

- lua\_pushcfunction(L, ngx\_http\_lua\_ngx\_re\_split);
- lua\_setfield(L, -2, “split”);
- lua\_setfield(L, -2, “re”);  
}

–  
1.7.9.5

2012/7/13 Jader H. Silva [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)
