Login Register
Frontpage Code library Pastebin

PatternCompare()

Author: Jare
Added: 20. syyskuuta 2013 kello 10.37
Edited: 11. maaliskuuta 2021 kello 17.25
Category: Merkkijonot

Description

Yksinkertainen jokerimerkin huomioiva merkkijonojen vertailu. Parametrit: - Merkkijono, joka saattaa sisältää jokerimerkkejä - Vertailtava merkkijono - Huomioidaanko kirjainkoko (oletuksena kyllä) - Käytettävä jokerimerkki (oletuksena *) - Escape-merkki, jonka syöttämällä jokerin eteen, jokeria käytetään tavallisena merkkinä. Aseta tyhjäksi, jos et halua käyttää escape-merkkiä. (oletuksena \). Edit 21.9.2013: Lisäsin escape-merkin. Edit 11.3.2021: Tässä funktiossa on bugi. Se palauttaa joskus false negativen, esimerkiksi PatternCompare("*ab", "abab") pitäisi olla true, mutta funktio hämmentyy koska alussa matchaavan "ab":n jälkeen tulee vielä merkkejä, eikä se hoksaa tarkistaa, että jokerimerkin voisi laajentaa matchaamaan ensimmäisen "ab":n, jonka jälkeen toinen "ab" matchattaisiin pattern$:n "ab":n kanssa. Sen sijaan toisessa esimerkissä funktio palauttaa truen ihan oikein: PatternCompare("*ab", "bab") (compare$:stä jätettiin pois ensimmäinen "a"). Ilmeisesti tämän funktion algoritmi on auttamattomasti liian yksinkertainen. Sen sijaan, että yrittäisin tekohengittää sitä jollain purkalla, etsin netistä itseäni viisaamman henkilön tekemän algoritmin ja porttasin sen CoolBasicille. Löydät sen täältä: https://github.com/Taitava/cb-PatternCompare Lisäksi uusi funktio ei tarvitse GetWord2() ja CountWords2() -funktioita. Uusi on myös testattu unit testeillä varmasti toimivaksi reilussa parissasadassa eri tilanteessa. Ai niin, se sisältää myös kysymysmerkki-jokerin, jota voidaan käyttää matchaamaan mikä tahansa _yksi_ merkki, eikä monta (tai ei yhtään) kuten * tekee. Jääköön tämä vanha versio PatternCompare():sta tänne CBRepositoryn puolelle vaikka "ei näin" -esimerkiksi. :)

Code

Select all
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
Function PatternCompare(pattern$, compare$, case_sensitive=1, wildcard$="*", escape$="\")
    position = 1
    If Not case_sensitive Then
        pattern = Lower(pattern)
        compare = Lower(compare)
    EndIf
    If escape <> "" Then
        pattern = Replace(pattern, escape+escape, Chr(1))
        pattern = Replace(pattern, escape+wildcard, Chr(2))
    EndIf
    count_bits = CountWords2(pattern, wildcard)
    For i = 1 To count_bits
        bit$    = GetWord2(pattern, i, wildcard)
        bit     = Replace(bit, Chr(1), escape)
        bit     = Replace(bit, Chr(2), wildcard)
        position= InStr(compare, bit, position)
        If position = 0 Then Return False
        If i = 1 And position > 1 And Left(pattern,1) <> wildcard Then Return False
        If i = count_bits And position < Len(compare) - Len(bit) + 1 And Right(pattern,1) <> wildcard Then Return False
    Next i
    Return True
EndFunction

Comments

No comments. You can be first!

Leave a comment

You must be logged in to comment.