📄 match.c
字号:
/* EPSHeader File: match.c Author: J. Kercheval Created: Sat, 01/05/1991 22:21:49*//* EPSRevision History J. Kercheval Wed, 02/20/1991 22:29:01 Released to Public Domain J. Kercheval Fri, 02/22/1991 15:29:01 fix '\' bugs (two :( of them) J. Kercheval Sun, 03/10/1991 19:31:29 add error return to matche() J. Kercheval Sun, 03/10/1991 20:11:11 add is_valid_pattern code J. Kercheval Sun, 03/10/1991 20:37:11 beef up main() J. Kercheval Tue, 03/12/1991 22:25:10 Released as V1.1 to Public Domain*//* Wildcard Pattern Matching*/#include "match.h"int matche_after_star (register char *pattern, register char *text);int fast_match_after_star (register char *pattern, register char *text);/*----------------------------------------------------------------------------** Return TRUE if PATTERN has any special wildcard characters*----------------------------------------------------------------------------*/BOOLEAN is_pattern (char *p){ while (*p) { switch (*p++) { case '?': case '*': case '[': case '\\': return TRUE; } } return FALSE;}/*----------------------------------------------------------------------------** Return TRUE if PATTERN has is a well formed regular expression according* to the above syntax** error_type is a return code based on the type of pattern error. Zero is* returned in error_type if the pattern is a valid one. error_type return* values are as follows:** PATTERN_VALID - pattern is well formed* PATTERN_ESC - pattern has invalid escape ('\' at end of pattern)* PATTERN_RANGE - [..] construct has a no end range in a '-' pair (ie [a-])* PATTERN_CLOSE - [..] construct has no end bracket (ie [abc-g )* PATTERN_EMPTY - [..] construct is empty (ie [])*----------------------------------------------------------------------------*/BOOLEAN is_valid_pattern (char *p, int *error_type){ /* init error_type */ *error_type = PATTERN_VALID; /* loop through pattern to EOS */ while (*p) { /* determine pattern type */ switch (*p) { /* check literal escape, it cannot be at end of pattern */ case '\\': if (!*++p) { *error_type = PATTERN_ESC; return FALSE; } p++; break; /* the [..] construct must be well formed */ case '[': p++; /* if the next character is ']' then bad pattern */ if (*p == ']') { *error_type = PATTERN_EMPTY; return FALSE; } /* if end of pattern here then bad pattern */ if (!*p) { *error_type = PATTERN_CLOSE; return FALSE; } /* loop to end of [..] construct */ while (*p != ']') { /* check for literal escape */ if (*p == '\\') { p++; /* if end of pattern here then bad pattern */ if (!*p++) { *error_type = PATTERN_ESC; return FALSE; } } else p++; /* if end of pattern here then bad pattern */ if (!*p) { *error_type = PATTERN_CLOSE; return FALSE; } /* if this a range */ if (*p == '-') { /* we must have an end of range */ if (!*++p || *p == ']') { *error_type = PATTERN_RANGE; return FALSE; } else { /* check for literal escape */ if (*p == '\\') p++; /* if end of pattern here then bad pattern */ if (!*p++) { *error_type = PATTERN_ESC; return FALSE; } } } } break; /* all other characters are valid pattern elements */ case '*': case '?': default: p++; /* "normal" character */ break; } } return TRUE;}/*----------------------------------------------------------------------------** Match the pattern PATTERN against the string TEXT;** returns MATCH_VALID if pattern matches, or an errorcode as follows* otherwise:** MATCH_PATTERN - bad pattern* MATCH_LITERAL - match failure on literal mismatch* MATCH_RANGE - match failure on [..] construct* MATCH_ABORT - premature end of text string* MATCH_END - premature end of pattern string* MATCH_VALID - valid match*** A match means the entire string TEXT is used up in matching.** In the pattern string:* `*' matches any sequence of characters (zero or more)* `?' matches any character* [SET] matches any character in the specified set,* [!SET] or [^SET] matches any character not in the specified set.** A set is composed of characters or ranges; a range looks like* character hyphen character (as in 0-9 or A-Z). [0-9a-zA-Z_] is the* minimal set of characters allowed in the [..] pattern construct.* Other characters are allowed (ie. 8 bit characters) if your system* will support them.** To suppress the special syntactic significance of any of `[]*?!^-\',* and match the character exactly, precede it with a `\'.*----------------------------------------------------------------------------*/int matche (register char *p, register char *t){ register char range_start, range_end; /* start and end in range */ BOOLEAN invert; /* is this [..] or [!..] */ BOOLEAN member_match; /* have I matched the [..] construct? */ BOOLEAN loop; /* should I terminate? */ for ( ; *p; p++, t++) { /* if this is the end of the text then this is the end of the match */ if (!*t) { return ( *p == '*' && *++p == '\0' ) ? MATCH_VALID : MATCH_ABORT; } /* determine and react to pattern type */ switch (*p) { case '?': /* single any character match */ break; case '*': /* multiple any character match */ return matche_after_star (p, t); /* [..] construct, single member/exclusion character match */ case '[': { /* move to beginning of range */ p++; /* check if this is a member match or exclusion match */ invert = FALSE; if (*p == '!' || *p == '^') { invert = TRUE; p++; } /* if closing bracket here or at range start then we have a malformed pattern */ if (*p == ']') { return MATCH_PATTERN; } member_match = FALSE; loop = TRUE; while (loop) { /* if end of construct then loop is done */ if (*p == ']') { loop = FALSE; continue; } /* matching a '!', '^', '-', '\' or a ']' */ if (*p == '\\') { range_start = range_end = *++p; } else range_start = range_end = *p; /* if end of pattern then bad pattern (Missing ']') */ if (!*p) return MATCH_PATTERN; /* check for range bar */ if (*++p == '-') { /* get the range end */ range_end = *++p; /* if end of pattern or construct then bad pattern */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -