regexp.c

来自「postgresql8.3.4源码,开源数据库」· C语言 代码 · 共 1,177 行 · 第 1/3 页

C
1,177
字号
					break;				case 't':		/* tight syntax */					flags->cflags &= ~REG_EXPANDED;					break;				case 'w':		/* weird, \n affects ^ $ only */					flags->cflags &= ~REG_NLSTOP;					flags->cflags |= REG_NLANCH;					break;				case 'x':		/* expanded syntax */					flags->cflags |= REG_EXPANDED;					break;				default:					ereport(ERROR,							(errcode(ERRCODE_INVALID_PARAMETER_VALUE),							 errmsg("invalid regexp option: \"%c\"",									opt_p[i])));					break;			}		}	}}/* * assign_regex_flavor - GUC hook to validate and set REGEX_FLAVOR */const char *assign_regex_flavor(const char *value, bool doit, GucSource source){	if (pg_strcasecmp(value, "advanced") == 0)	{		if (doit)			regex_flavor = REG_ADVANCED;	}	else if (pg_strcasecmp(value, "extended") == 0)	{		if (doit)			regex_flavor = REG_EXTENDED;	}	else if (pg_strcasecmp(value, "basic") == 0)	{		if (doit)			regex_flavor = REG_BASIC;	}	else		return NULL;			/* fail */	return value;				/* OK */}/* * report whether regex_flavor is currently BASIC */boolregex_flavor_is_basic(void){	return (regex_flavor == REG_BASIC);}/* *	interface routines called by the function manager */Datumnameregexeq(PG_FUNCTION_ARGS){	Name		n = PG_GETARG_NAME(0);	text	   *p = PG_GETARG_TEXT_PP(1);	PG_RETURN_BOOL(RE_compile_and_execute(p,										  NameStr(*n),										  strlen(NameStr(*n)),										  regex_flavor,										  0, NULL));}Datumnameregexne(PG_FUNCTION_ARGS){	Name		n = PG_GETARG_NAME(0);	text	   *p = PG_GETARG_TEXT_PP(1);	PG_RETURN_BOOL(!RE_compile_and_execute(p,										   NameStr(*n),										   strlen(NameStr(*n)),										   regex_flavor,										   0, NULL));}Datumtextregexeq(PG_FUNCTION_ARGS){	text	   *s = PG_GETARG_TEXT_PP(0);	text	   *p = PG_GETARG_TEXT_PP(1);	PG_RETURN_BOOL(RE_compile_and_execute(p,										  VARDATA_ANY(s),										  VARSIZE_ANY_EXHDR(s),										  regex_flavor,										  0, NULL));}Datumtextregexne(PG_FUNCTION_ARGS){	text	   *s = PG_GETARG_TEXT_PP(0);	text	   *p = PG_GETARG_TEXT_PP(1);	PG_RETURN_BOOL(!RE_compile_and_execute(p,										   VARDATA_ANY(s),										   VARSIZE_ANY_EXHDR(s),										   regex_flavor,										   0, NULL));}/* *	routines that use the regexp stuff, but ignore the case. *	for this, we use the REG_ICASE flag to pg_regcomp */Datumnameicregexeq(PG_FUNCTION_ARGS){	Name		n = PG_GETARG_NAME(0);	text	   *p = PG_GETARG_TEXT_PP(1);	PG_RETURN_BOOL(RE_compile_and_execute(p,										  NameStr(*n),										  strlen(NameStr(*n)),										  regex_flavor | REG_ICASE,										  0, NULL));}Datumnameicregexne(PG_FUNCTION_ARGS){	Name		n = PG_GETARG_NAME(0);	text	   *p = PG_GETARG_TEXT_PP(1);	PG_RETURN_BOOL(!RE_compile_and_execute(p,										   NameStr(*n),										   strlen(NameStr(*n)),										   regex_flavor | REG_ICASE,										   0, NULL));}Datumtexticregexeq(PG_FUNCTION_ARGS){	text	   *s = PG_GETARG_TEXT_PP(0);	text	   *p = PG_GETARG_TEXT_PP(1);	PG_RETURN_BOOL(RE_compile_and_execute(p,										  VARDATA_ANY(s),										  VARSIZE_ANY_EXHDR(s),										  regex_flavor | REG_ICASE,										  0, NULL));}Datumtexticregexne(PG_FUNCTION_ARGS){	text	   *s = PG_GETARG_TEXT_PP(0);	text	   *p = PG_GETARG_TEXT_PP(1);	PG_RETURN_BOOL(!RE_compile_and_execute(p,										   VARDATA_ANY(s),										   VARSIZE_ANY_EXHDR(s),										   regex_flavor | REG_ICASE,										   0, NULL));}/* * textregexsubstr() *		Return a substring matched by a regular expression. */Datumtextregexsubstr(PG_FUNCTION_ARGS){	text	   *s = PG_GETARG_TEXT_PP(0);	text	   *p = PG_GETARG_TEXT_PP(1);	regex_t    *re;	regmatch_t	pmatch[2];	int			so,				eo;	/* Compile RE */	re = RE_compile_and_cache(p, regex_flavor);	/*	 * We pass two regmatch_t structs to get info about the overall match and	 * the match for the first parenthesized subexpression (if any). If there	 * is a parenthesized subexpression, we return what it matched; else	 * return what the whole regexp matched.	 */	if (!RE_execute(re,					VARDATA_ANY(s), VARSIZE_ANY_EXHDR(s),					2, pmatch))		PG_RETURN_NULL();		/* definitely no match */	if (re->re_nsub > 0)	{		/* has parenthesized subexpressions, use the first one */		so = pmatch[1].rm_so;		eo = pmatch[1].rm_eo;	}	else	{		/* no parenthesized subexpression, use whole match */		so = pmatch[0].rm_so;		eo = pmatch[0].rm_eo;	}	/*	 * It is possible to have a match to the whole pattern but no match	 * for a subexpression; for example 'foo(bar)?' is considered to match	 * 'foo' but there is no subexpression match.  So this extra test for	 * match failure is not redundant.	 */	if (so < 0 || eo < 0)		PG_RETURN_NULL();	return DirectFunctionCall3(text_substr,							   PointerGetDatum(s),							   Int32GetDatum(so + 1),							   Int32GetDatum(eo - so));}/* * textregexreplace_noopt() *		Return a string matched by a regular expression, with replacement. * * This version doesn't have an option argument: we default to case * sensitive match, replace the first instance only. */Datumtextregexreplace_noopt(PG_FUNCTION_ARGS){	text	   *s = PG_GETARG_TEXT_PP(0);	text	   *p = PG_GETARG_TEXT_PP(1);	text	   *r = PG_GETARG_TEXT_PP(2);	regex_t    *re;	re = RE_compile_and_cache(p, regex_flavor);	PG_RETURN_TEXT_P(replace_text_regexp(s, (void *) re, r, false));}/* * textregexreplace() *		Return a string matched by a regular expression, with replacement. */Datumtextregexreplace(PG_FUNCTION_ARGS){	text	   *s = PG_GETARG_TEXT_PP(0);	text	   *p = PG_GETARG_TEXT_PP(1);	text	   *r = PG_GETARG_TEXT_PP(2);	text	   *opt = PG_GETARG_TEXT_PP(3);	regex_t    *re;	pg_re_flags flags;	parse_re_flags(&flags, opt);	re = RE_compile_and_cache(p, flags.cflags);	PG_RETURN_TEXT_P(replace_text_regexp(s, (void *) re, r, flags.glob));}/* * similar_escape() * Convert a SQL99 regexp pattern to POSIX style, so it can be used by * our regexp engine. */Datumsimilar_escape(PG_FUNCTION_ARGS){	text	   *pat_text;	text	   *esc_text;	text	   *result;	char	   *p,			   *e,			   *r;	int			plen,				elen;	bool		afterescape = false;	int			nquotes = 0;	/* This function is not strict, so must test explicitly */	if (PG_ARGISNULL(0))		PG_RETURN_NULL();	pat_text = PG_GETARG_TEXT_PP(0);	p = VARDATA_ANY(pat_text);	plen = VARSIZE_ANY_EXHDR(pat_text);	if (PG_ARGISNULL(1))	{		/* No ESCAPE clause provided; default to backslash as escape */		e = "\\";		elen = 1;	}	else	{		esc_text = PG_GETARG_TEXT_PP(1);		e = VARDATA_ANY(esc_text);		elen = VARSIZE_ANY_EXHDR(esc_text);		if (elen == 0)			e = NULL;			/* no escape character */		else if (elen != 1)			ereport(ERROR,					(errcode(ERRCODE_INVALID_ESCAPE_SEQUENCE),					 errmsg("invalid escape string"),				  errhint("Escape string must be empty or one character.")));	}	/*----------	 * We surround the transformed input string with	 *			***:^(?: ... )$	 * which is bizarre enough to require some explanation.  "***:" is a	 * director prefix to force the regex to be treated as an ARE regardless	 * of the current regex_flavor setting.  We need "^" and "$" to force	 * the pattern to match the entire input string as per SQL99 spec.	The	 * "(?:" and ")" are a non-capturing set of parens; we have to have	 * parens in case the string contains "|", else the "^" and "$" will	 * be bound into the first and last alternatives which is not what we	 * want, and the parens must be non capturing because we don't want them	 * to count when selecting output for SUBSTRING.	 *----------	 */	/*	 * We need room for the prefix/postfix plus as many as 2 output bytes per	 * input byte	 */	result = (text *) palloc(VARHDRSZ + 10 + 2 * plen);	r = VARDATA(result);	*r++ = '*';	*r++ = '*';	*r++ = '*';	*r++ = ':';	*r++ = '^';	*r++ = '(';	*r++ = '?';	*r++ = ':';	while (plen > 0)	{		char		pchar = *p;		if (afterescape)		{			if (pchar == '"')	/* for SUBSTRING patterns */				*r++ = ((nquotes++ % 2) == 0) ? '(' : ')';			else			{				*r++ = '\\';				*r++ = pchar;			}			afterescape = false;		}		else if (e && pchar == *e)		{			/* SQL99 escape character; do not send to output */			afterescape = true;		}		else if (pchar == '%')		{			*r++ = '.';			*r++ = '*';		}		else if (pchar == '_')			*r++ = '.';		else if (pchar == '\\' || pchar == '.' || pchar == '?' ||				 pchar == '{')		{			*r++ = '\\';			*r++ = pchar;		}		else			*r++ = pchar;		p++, plen--;	}	*r++ = ')';	*r++ = '$';	SET_VARSIZE(result, r - ((char *) result));	PG_RETURN_TEXT_P(result);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?