Если без рекурсии, то как-то так:
MODULE Match;
IMPORT Strings;
PROCEDURE MatchIt( CONST text, pattern : ARRAY OF CHAR;
posT, posP : LONGINT;
lenT, lenP : LONGINT ): BOOLEAN;
VAR chT, chP: CHAR;
PROCEDURE NoMoreCharInPattern(): BOOLEAN;
BEGIN
WHILE ( pattern[ posP ] = '*' ) & ( posP # lenP ) DO
INC( posP );
END;
RETURN posP = lenP;
END NoMoreCharInPattern;
PROCEDURE FindCharInText( ch: CHAR ): BOOLEAN;
BEGIN
WHILE posT # lenT DO
IF text[ posT ] = ch THEN RETURN TRUE END;
INC ( posT );
END;
RETURN FALSE;
END FindCharInText;
BEGIN
LOOP
IF posT = lenT THEN
RETURN NoMoreCharInPattern();
ELSIF posP = lenP THEN
RETURN FALSE;
ELSE
chT := text[ posT ];
chP := pattern[ posP ];
IF chP = '*' THEN
INC( posP );
IF NoMoreCharInPattern() THEN
RETURN TRUE;
ELSIF FindCharInText( pattern[ posP ] ) THEN
INC( posT );
INC( posP );
ELSE
RETURN FALSE;
END;
ELSIF ( chP = chT ) OR ( chP = '?' ) THEN
INC( posT );
INC( posP );
ELSE
RETURN FALSE;
END;
END;
END;
END MatchIt;
PROCEDURE DoMatch*( CONST text, pattern: ARRAY OF CHAR ): BOOLEAN;
BEGIN
RETURN MatchIt( text, pattern, 0, 0, Strings.Length( text ), Strings.Length( pattern ));
END DoMatch;
END Match.
'?' вроде тоже должна работать, при условии, что стоит не перед звездой, но кто ее перед звездой ставит...