mirror of
https://github.com/rsyslog/rsyslog.git
synced 2025-12-18 02:50:43 +01:00
capability for replacement text in no match regex case added
implemented in property replacer: if a regular expression does not match, it can now either return "**NO MATCH** (default, as before), a blank property or the full original property text
This commit is contained in:
parent
99f18190a1
commit
6a815063f3
@ -4,6 +4,9 @@ Version 3.19.5 (rgerhards), 2008-05-??
|
||||
(previously BRE was permitted only)
|
||||
- provided ability to specify that a regular expression submatch shall
|
||||
be used inside the property replacer
|
||||
- implemented in property replacer: if a regular expression does not match,
|
||||
it can now either return "**NO MATCH** (default, as before), a blank
|
||||
property or the full original property text
|
||||
---------------------------------------------------------------------------
|
||||
Version 3.19.4 (rgerhards), 2008-05-27
|
||||
- implemented x509/certvalid gtls auth mode
|
||||
|
||||
@ -207,16 +207,23 @@ sequence with a regular expression is: "%msg:R:.*Sev:. \(.*\)
|
||||
\[.*--end%"</p>
|
||||
<p>It is possible to specify some parametes after the "R". These are
|
||||
comma-separated. They are:
|
||||
<p>R,<regexp-type>,<submatch>
|
||||
<p>R,<regexp-type>,<submatch>,<nomatch>
|
||||
<p>regexp-type is either "BRE" for Posix basic regular expressions or
|
||||
"ERE" for extended ones. The string must be given in upper case. The
|
||||
default is "BRE" to be consistent with earlier versions of rsyslog that
|
||||
did not support ERE. The submatch identifies the submatch to be used
|
||||
with the result. A single digit is supported. Match 0 is the full match,
|
||||
while 1 to 9 are the acutal submatches.
|
||||
<p>nomatch is either "DFLT", "BLANK" or "FIELD" (all upper case!). It tells
|
||||
what to use if no match is found. With "DFLT", the strig "**NO MATCH**" is
|
||||
used. This was the only supported value up to rsyslog 3.19.5. With "BLANK"
|
||||
a blank text is used (""). Finally, "FIELD" uses the full property text
|
||||
instead of the expression. Some folks have requested that, so it seems
|
||||
to be useful.
|
||||
<p>The following is a sample of an ERE expression that takes the first
|
||||
submatch from the message string:
|
||||
<p>%msg:R,ERE,1:for (vlan[0-9]*):--end%
|
||||
submatch from the message string and replaces the expression with
|
||||
the full field if no match is found:
|
||||
<p>%msg:R,ERE,1,FIELD:for (vlan[0-9]*):--end%
|
||||
<p><b>Also, extraction can be done based on so-called
|
||||
"fields"</b>. To do so, place a "F" into FromChar. A field in its
|
||||
current definition is anything that is delimited by a delimiter
|
||||
|
||||
@ -1844,25 +1844,30 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
|
||||
if(objUse(regexp, LM_REGEXP_FILENAME) == RS_RET_OK) {
|
||||
if (0 != regexp.regexec(&pTpe->data.field.re, pRes, nmatch, pmatch, 0)) {
|
||||
/* we got no match! */
|
||||
if (*pbMustBeFreed == 1) {
|
||||
free(pRes);
|
||||
*pbMustBeFreed = 0;
|
||||
}
|
||||
return "**NO MATCH**";
|
||||
} else {
|
||||
{int i; for(i = 0 ; i < 10 ; ++i) {
|
||||
dbgprintf("rqtd regex match (nmatch %d) # %d, idx %d: so %d, eo %d\n", nmatch, pTpe->data.field.iMatchToUse, i,
|
||||
pmatch[i].rm_so,
|
||||
pmatch[i].rm_eo);
|
||||
}}
|
||||
/* Match- but did it match the one we wanted? */
|
||||
/* we got no match! */
|
||||
if(pmatch[pTpe->data.field.iMatchToUse].rm_so == -1) {
|
||||
if(pTpe->data.field.nomatchAction != TPL_REGEX_NOMATCH_USE_WHOLE_FIELD) {
|
||||
if (*pbMustBeFreed == 1) {
|
||||
free(pRes);
|
||||
*pbMustBeFreed = 0;
|
||||
}
|
||||
return "**NO MATCH**";
|
||||
if(pTpe->data.field.nomatchAction == TPL_REGEX_NOMATCH_USE_DFLTSTR)
|
||||
return "**NO MATCH**";
|
||||
else
|
||||
return "";
|
||||
}
|
||||
} else {
|
||||
/* Match- but did it match the one we wanted? */
|
||||
/* we got no match! */
|
||||
if(pmatch[pTpe->data.field.iMatchToUse].rm_so == -1) {
|
||||
if(pTpe->data.field.nomatchAction != TPL_REGEX_NOMATCH_USE_WHOLE_FIELD) {
|
||||
if (*pbMustBeFreed == 1) {
|
||||
free(pRes);
|
||||
*pbMustBeFreed = 0;
|
||||
}
|
||||
if(pTpe->data.field.nomatchAction == TPL_REGEX_NOMATCH_USE_DFLTSTR)
|
||||
return "**NO MATCH**";
|
||||
else
|
||||
return "";
|
||||
}
|
||||
}
|
||||
/* OK, we have a usable match - we now need to malloc pB */
|
||||
int iLenBuf;
|
||||
|
||||
25
template.c
25
template.c
@ -521,10 +521,10 @@ static int do_Parameter(unsigned char **pp, struct template *pTpl)
|
||||
/* first come the regex type */
|
||||
if(*p == ',') {
|
||||
++p; /* eat ',' */
|
||||
if(*p == 'B' && *(p+1) == 'R' && *(p+2) == 'E' && *(p+3) == ',') {
|
||||
if(p[0] == 'B' && p[1] == 'R' && p[2] == 'E' && (p[3] == ',' || p[3] == ':')) {
|
||||
pTpe->data.field.typeRegex = TPL_REGEX_BRE;
|
||||
p += 3; /* eat indicator sequence */
|
||||
} else if(*p == 'E' && *(p+1) == 'R' && *(p+2) == 'E' && *(p+3) == ',') {
|
||||
} else if(p[0] == 'E' && p[1] == 'R' && p[2] == 'E' && (p[3] == ',' || p[3] == ':')) {
|
||||
pTpe->data.field.typeRegex = TPL_REGEX_ERE;
|
||||
p += 3; /* eat indicator sequence */
|
||||
} else {
|
||||
@ -546,6 +546,27 @@ static int do_Parameter(unsigned char **pp, struct template *pTpl)
|
||||
}
|
||||
}
|
||||
|
||||
/* now pull what to do if we do not find a match */
|
||||
if(*p == ',') {
|
||||
++p; /* eat ',' */
|
||||
if(p[0] == 'D' && p[1] == 'F' && p[2] == 'L' && p[3] == 'T'
|
||||
&& (p[4] == ',' || p[4] == ':')) {
|
||||
pTpe->data.field.nomatchAction = TPL_REGEX_NOMATCH_USE_DFLTSTR;
|
||||
p += 4; /* eat indicator sequence */
|
||||
} else if(p[0] == 'B' && p[1] == 'L' && p[2] == 'A' && p[3] == 'N' && p[4] == 'K'
|
||||
&& (p[5] == ',' || p[5] == ':')) {
|
||||
pTpe->data.field.nomatchAction = TPL_REGEX_NOMATCH_USE_BLANK;
|
||||
p += 5; /* eat indicator sequence */
|
||||
} else if(p[0] == 'F' && p[1] == 'I' && p[2] == 'E' && p[3] == 'L' && p[4] == 'D'
|
||||
&& (p[5] == ',' || p[5] == ':')) {
|
||||
pTpe->data.field.nomatchAction = TPL_REGEX_NOMATCH_USE_WHOLE_FIELD;
|
||||
p += 5; /* eat indicator sequence */
|
||||
} else {
|
||||
errmsg.LogError(NO_ERRCODE, "error: invalid regular expression type, rest of line %s",
|
||||
(char*) p);
|
||||
}
|
||||
}
|
||||
|
||||
if(*p != ':') {
|
||||
/* There is something more than an R , this is invalid ! */
|
||||
/* Complain on extra characters */
|
||||
|
||||
@ -73,6 +73,11 @@ struct templateEntry {
|
||||
TPL_REGEX_BRE = 0, /* posix BRE */
|
||||
TPL_REGEX_ERE = 1 /* posix ERE */
|
||||
} typeRegex;
|
||||
enum {
|
||||
TPL_REGEX_NOMATCH_USE_DFLTSTR = 0, /* use the (old style) default "**NO MATCH**" string */
|
||||
TPL_REGEX_NOMATCH_USE_BLANK = 1, /* use a blank string */
|
||||
TPL_REGEX_NOMATCH_USE_WHOLE_FIELD = 2 /* use the full field contents that we were searching in*/
|
||||
} nomatchAction; /**< what to do if we do not have a match? */
|
||||
|
||||
#endif
|
||||
unsigned has_fields; /* support for field-counting: field to extract */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user