Cycorder comparison function for replacing MaskMatch

xiaoxiao2021-03-06  40

Delphi

Wildcard matching function

Tmask.matches

Some problems: If the wildcard strings are too long, such as entry

Hotmail

The address of the mailbox has probably

250

Character. This will result in

Tmask.matches

The function is wrong and causes the entire program to crash. I have found some different implementations online and do performance comparisons. Now I have an optimized version to share it.

Type

TmaskmatchResult =

Record

Ofsets: Integer; Patternlength: Integer;

end

;

FUNCTION

Haswildcardsa

Const

S:

String

: Boolean;

VAR

I: integer;

Begin

Result: = FALSE;

for

I: =

1

TO

Length (s)

DO

IF

S [i]

in

[

'*'

,

'?'

]

THEN

Begin

Result: = true;

end

;

end

;

// Idicates WHETHER A STRING MATCHES A WILDCARD PATTERN.

FUNCTION

Matchmaska ​​(

Const

Apattern, Asource:

String

: Boolean;

VAR

I: integer;

Begin

IF

Apattern =

'' '

THEN

Result: = asource =

'' '

Else

IF

Asource =

'' '

THEN

Begin

for

I: =

1

TO

Length (apattern)

DO

IF

Apattern [i] <>

'*'

THEN

Begin

Result: = FALSE; EXIT;

end

Result: = true;

end

Else

Result: = MatchmasKexa (Apattern, Asource) .patternlength = length (asource);

end

;

// Idicates WHETHER A STRING MATCHES A WILDCARD PATTERN.

//

When not matched, result.patternlength = 0.

FUNCTION

Matchmaskexa (

Const

Apattern, Asource:

String

; Offset: integer =

1

ScanPattern: Boolean = True): TmaskmatchResult;

VAR

Stringptr, stringres, patternptr, patternres: pchar; countingflexibleLength: boolean; i: integer;

Begin

Fillchar (Result, SIZEOF (Result),

#

0

);

IF

Offset <

1

THEN

OFFSET: =

1

;

IF

Scanpattern

and

NOT

Haswildcardsa (Apattern)

THEN

Begin

IF

OFFSET = POSEX

{ANSI ONLY}

(Apattern, Asource, Offset)

THEN

Begin

Result.patternlength: = Length (apattern) {!> 0}

Result.offset: = offset

end

EXIT;

end

Stringptr: = pchar (asource);

IF

Offset>

1

THEN

INC (Stringptr, Offset)

1

Patternptr: = pchar (apattern); stringRES: =

NIL

Patternres: =

NIL

CountingflexibleLength: = (Length (apattern)>

0

)

and

(Apattern [

1

] =

'*'

);

Repeat

Repeat

// ohne vorancegangenes "*"

Case

Patternptr ^

Of

#

0

:

Begin

Result.patternlength: = Length (Asource) (

1

- offset - Length (Stringptr);

IF

Result.patternlength>

0

THEN

RESULT.OFFSET: = OFFSET;

end

;

'*'

:

Begin

INC; PATTERNRES: = Patternptr; Break;

end

;

'?'

:

Begin

IF

Stringptr ^ =

#

0

THEN

EXIT; INC (Stringptr); Inc (Patternptr);

end

;

Else

Begin

IF

Stringptr ^ =

#

0

THEN

EXIT;

IF

Stringptr ^ <> patternptr ^

THEN

Begin

IF

(StringRes =

NIL

)

oral

(PatternRes =

NIL

)

THEN

Stringptr: = stringRES; Patternptr: = Patternres; Break;

end

Else

Begin

Inc (StringPtr); Inc (Patternptr);

end

;

end

;

end

;

Until

False;

Repeat

// mit vorancegangenem "*"

Case

Patternptr ^

Of

#

0

:

Begin

Result.patternlength: = Length (Asource) (

1

- offset;

IF

ANSILASTCHAR (APATTERN) <>

'*'

THEN

Dec (Result.Patternlength);

IF

Result.patternlength>

0

THEN

Result.offset: = offset

IF

CountingflexibleLength

THEN

Result.LeadingflexibleLength: = Result.patternlength; exit;

;

'*'

:

Begin

INC; Patternres: = Patternptr;

end

;

'?'

:

Begin

IF

Stringptr ^ =

#

0

THEN

EXIT; INC (Stringptr); Inc (Patternptr);

end

;

Else

Begin

Repeat

IF

Stringptr ^ =

#

0

THEN

EXIT;

IF

Stringptr ^ = patternptr ^

THEN

Break; inc (StringPtr);

Until

False; Inc (Stringptr); stringRES: = StringPtr; Inc (Patternptr); Break;

end

;

end

;

Until

False;

IF

CountingflexibleLength

THEN

Begin

Result.LeadingflexibleLength: = Length (asource) - offset - length (stringptr); countingflexibleLength: = false;

end

;

Until

False;

end

;

转载请注明原文地址:https://www.9cbs.com/read-118503.html

New Post(0)