Косметика + условие для учета '?' + дополнительные тесты на прохождение '?':
MODULE Match;
IMPORT Log := KernelLog, Strings;
PROCEDURE MatchIt( CONST text, pattern : ARRAY OF CHAR;
posT, posP : LONGINT;
lenT, lenP : LONGINT ): BOOLEAN;
VAR
chT, chP: CHAR;
iT, iP : LONGINT;
PROCEDURE NoMoreCharInPattern(): BOOLEAN;
BEGIN
WHILE ( posP # lenP ) & ( pattern[ posP ] = '*' ) DO
INC( posP );
END;
RETURN posP = lenP;
END NoMoreCharInPattern;
PROCEDURE FindCharInText( ch: CHAR; pos: LONGINT ): BOOLEAN;
BEGIN
WHILE pos # lenT DO
IF ( text[ pos ] = ch ) OR ( ch = '?' ) THEN posT := pos; RETURN TRUE END;
INC ( pos );
END;
RETURN FALSE;
END FindCharInText;
PROCEDURE Retry;
BEGIN
posP := iP;
INC( posP );
INC( posT );
iT := posT;
END Retry;
BEGIN
iT := lenT;
iP := lenP;
LOOP
IF posT = lenT THEN
RETURN NoMoreCharInPattern();
ELSIF posP = lenP THEN
IF ( iP # lenP ) & FindCharInText( pattern[iP] , iT ) THEN
Retry
ELSE
RETURN FALSE;
END;
ELSE
chT := text[ posT ];
chP := pattern[ posP ];
IF chP = '*' THEN
INC( posP );
IF NoMoreCharInPattern() THEN RETURN TRUE END;
chP := pattern[ posP ];
IF FindCharInText( chP, posT ) THEN
iP := posP;
INC( posP );
INC( posT );
iT := posT;
ELSE
RETURN FALSE;
END;
ELSIF ( chP = chT ) OR ( chP = '?' ) THEN
INC( posP );
INC( posT );
ELSE
IF ( iP # lenP ) & FindCharInText( pattern[iP] , iT ) THEN
Retry;
ELSE
RETURN FALSE;
END;
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;
PROCEDURE Test;
BEGIN
Log.String( "=========================================" ); Log.Ln;
Log.String( " 1)'' $ '' = " );
Log.Boolean( DoMatch( '' , '' ));
Log.Ln;
Log.String( " 2)'' $ 'a' = " );
Log.Boolean( DoMatch( '' , 'a' ));
Log.Ln;
Log.String( " 3)'' $ '*' = " );
Log.Boolean( DoMatch( '' , '*' ));
Log.Ln;
Log.String( " 4)'a' $ '' = " );
Log.Boolean( DoMatch( 'a' , '' ));
Log.Ln;
Log.String( " 5)'abcxyz' $ '*' = " );
Log.Boolean( DoMatch( 'abcxyz' , '*' ));
Log.Ln;
Log.String( " 6)'abcxyz' $ 'ab*' = " );
Log.Boolean( DoMatch( 'abcxyz' , 'ab*' ));
Log.Ln;
Log.String( " 7)'abcxyz' $ '*ab' = " );
Log.Boolean( DoMatch( 'abcxyz' , '*ab' ));
Log.Ln;
Log.String( " 8)'abcxyz' $ '*yz' = " );
Log.Boolean( DoMatch( 'abcxyz' , '*yz' ));
Log.Ln;
Log.String( " 9)'abcxyz' $ '*yz*' = " );
Log.Boolean( DoMatch( 'abcxyz' , '*yz*' ));
Log.Ln;
Log.String( "10)'abcxyz' $ 'ab*yz' = " );
Log.Boolean( DoMatch( 'abcxyz' , 'ab*yz' ));
Log.Ln;
Log.String( "11)'abcxyz' $ '*cx*' = " );
Log.Boolean( DoMatch( 'abcxyz' , '*cx*' ));
Log.Ln;
Log.String( "12)'abcxyz' $ '*a*c*y*' = " );
Log.Boolean( DoMatch( 'abcxyz' , '*a*c*y*' ));
Log.Ln;
Log.String( "13)'abcxyz' $ 'a*b***c*z' ) = " );
Log.Boolean( DoMatch( 'abcxyz' , 'a*b***c*z' ));
Log.Ln;
Log.String( "14)'abcxyz' $ '**a*b***y*z**' ) = " );
Log.Boolean( DoMatch( 'abcxyz' , '**a*b***y*z**' ));
Log.Ln;
Log.String( "15)'abcxyz' $ 'ab*x*c*yz' ) = " );
Log.Boolean( DoMatch( 'abcxyz' , 'ab*x*c*yz' ));
Log.Ln;
Log.String( "16)'abcxyz' $ '*cx' ) = " );
Log.Boolean( DoMatch( 'abcxyz' , '*cx' ));
Log.Ln;
Log.String( "17)'abcxyxyz' $ '*xyz' ) = " );
Log.Boolean( DoMatch( 'abcxyxyz' , '*xyz' ));
Log.Ln;
Log.String( "18)'abcxyzxy' $ '*xyz' ) = " );
Log.Boolean( DoMatch( 'abcxyzxy' , '*xyz' ));
Log.Ln;
Log.String( "19)'abcxyzxyz' $ '*xyz' ) = " );
Log.Boolean( DoMatch( 'abcxyzxyz' , '*xyz' ));
Log.Ln;
Log.String( "20)'abcxyzxyz' $ '*xyz*xyz' ) = " );
Log.Boolean( DoMatch( 'abcxyzxyz' , '*xyz*xyz' ));
Log.Ln;
Log.String( "21)'' $ '?' ) = " );
Log.Boolean( DoMatch( '' , '?' ));
Log.Ln;
Log.String( "22)'a' $ '?' ) = " );
Log.Boolean( DoMatch( 'a' , '?' ));
Log.Ln;
Log.String( "23)'az' $ '?' ) = " );
Log.Boolean( DoMatch( 'az' , '?' ));
Log.Ln;
Log.String( "24)'az' $ '??' ) = " );
Log.Boolean( DoMatch( 'az' , '??' ));
Log.Ln;
Log.String( "25)'az' $ '?*?' ) = " );
Log.Boolean( DoMatch( 'az' , '?*?' ));
Log.Ln;
Log.String( "26)'abyz' $ '?*?' ) = " );
Log.Boolean( DoMatch( 'abyz' , '?*?' ));
Log.Ln;
Log.String( "27)'abyz' $ '?*?*' ) = " );
Log.Boolean( DoMatch( 'abyz' , '?*?*' ));
Log.Ln;
Log.String( "28)'abcxyzxyz' $ '*?*' ) = " );
Log.Boolean( DoMatch( 'abcxyzxyz' , '*?*' ));
Log.Ln;
Log.String( "29)'abcxyzxyz' $ '*xyz*?yz' ) = " );
Log.Boolean( DoMatch( 'abcxyzxyz' , '*xyz*?yz' ));
Log.Ln;
Log.String( "30)'abcxyzxyz' $ '*?xyz*?yz' ) = " );
Log.Boolean( DoMatch( 'abcxyzxyz' , '*?xyz*?yz' ));
Log.Ln;
Log.String( "31)'abcxyzxyz' $ '?*xyz*y?' ) = " );
Log.Boolean( DoMatch( 'abcxyzxyz' , '?*xyz*y?' ));
Log.Ln;
Log.String( "32)'abcxyzxyz' $ '*x?z' ) = " );
Log.Boolean( DoMatch( 'abcxyzxyz' , '*x?z' ));
Log.Ln;
Log.String( "33)'abcxyzxyz' $ '*xyz*x?z' ) = " );
Log.Boolean( DoMatch( 'abcxyzxyz' , '*xyz*x?z' ));
Log.Ln;
Log.String( "34)'abcxyzxyz' $ '*x?z*x?z' ) = " );
Log.Boolean( DoMatch( 'abcxyzxyz' , '*x?z*x?z' ));
Log.Ln;
Log.String( "35)'abcxyzxyz' $ '*??x?z*x?z' ) = " );
Log.Boolean( DoMatch( 'abcxyzxyz' , '*??x?z*x?z' ));
Log.Ln;
Log.String( "36)'abcxyzxyz' $ '*??x?0z*x?z' ) = " );
Log.Boolean( DoMatch( 'abcxyzxyz' , '*??x?0z*x?z' ));
Log.Ln;
Log.String( "37)'abcxyzxyz' $ '*??x?z?*x?z' ) = " );
Log.Boolean( DoMatch( 'abcxyzxyz' , '*??x?z?*x?z' ));
Log.Ln;
Log.String( "38)'abcxyzxyz' $ '*??x?z?*?z' ) = " );
Log.Boolean( DoMatch( 'abcxyzxyz' , '*??x?z?*?z' ));
Log.Ln;
Log.String( "39)'abcxyz0xyz' $ '*??x?z?*x?z' ) = " );
Log.Boolean( DoMatch( 'abcxyz0xyz' , '*??x?z?*x?z' ));
Log.Ln;
Log.String( "=========================================" ); Log.Ln;
END Test;
PROCEDURE Do*;
BEGIN
Test;
END Do;
END Match.
SystemTools.Free Match ~
Match.Do~
Результаты тестов:
1)'' $ '' = TRUE
2)'' $ 'a' = FALSE
3)'' $ '*' = TRUE
4)'a' $ '' = FALSE
5)'abcxyz' $ '*' = TRUE
6)'abcxyz' $ 'ab*' = TRUE
7)'abcxyz' $ '*ab' = FALSE
8)'abcxyz' $ '*yz' = TRUE
9)'abcxyz' $ '*yz*' = TRUE
10)'abcxyz' $ 'ab*yz' = TRUE
11)'abcxyz' $ '*cx*' = TRUE
12)'abcxyz' $ '*a*c*y*' = TRUE
13)'abcxyz' $ 'a*b***c*z' ) = TRUE
14)'abcxyz' $ '**a*b***y*z**' ) = TRUE
15)'abcxyz' $ 'ab*x*c*yz' ) = FALSE
16)'abcxyz' $ '*cx' ) = FALSE
17)'abcxyxyz' $ '*xyz' ) = TRUE
18)'abcxyzxy' $ '*xyz' ) = FALSE
19)'abcxyzxyz' $ '*xyz' ) = TRUE
20)'abcxyzxyz' $ '*xyz*xyz' ) = TRUE
21)'' $ '?' ) = FALSE
22)'a' $ '?' ) = TRUE
23)'az' $ '?' ) = FALSE
24)'az' $ '??' ) = TRUE
25)'az' $ '?*?' ) = TRUE
26)'abyz' $ '?*?' ) = TRUE
27)'abyz' $ '?*?*' ) = TRUE
28)'abcxyzxyz' $ '*?*' ) = TRUE
29)'abcxyzxyz' $ '*xyz*?yz' ) = TRUE
30)'abcxyzxyz' $ '*?xyz*?yz' ) = TRUE
31)'abcxyzxyz' $ '?*xyz*y?' ) = TRUE
32)'abcxyzxyz' $ '*x?z' ) = TRUE
33)'abcxyzxyz' $ '*xyz*x?z' ) = TRUE
34)'abcxyzxyz' $ '*x?z*x?z' ) = TRUE
35)'abcxyzxyz' $ '*??x?z*x?z' ) = TRUE
36)'abcxyzxyz' $ '*??x?0z*x?z' ) = FALSE
37)'abcxyzxyz' $ '*??x?z?*x?z' ) = FALSE
38)'abcxyzxyz' $ '*??x?z?*?z' ) = TRUE
39)'abcxyz0xyz' $ '*??x?z?*x?z' ) = TRUE