"Als je het kan bedenken, kan het gemaakt worden" Parcye - 14 januari 2002
Nee, ik sla alle clubs stadions en spelers op in een TStringList en daar wil ik door zoeken met wildcards
"Als je het kan bedenken, kan het gemaakt worden" Parcye - 14 januari 2002
Verwijderd
Zoeken bij Google op "delphi regular expression" levert 10 pagina's aan hits op. Zal best wel iets bruikbaars tussen zitten...
Verwijderd
Beetje overdreven dat 'ie daar een eigen class voor in 't leven roept, maar alla...Op dinsdag 04 december 2001 20:12 schreef DiFool het volgende:
Of bv hier
Wanneer je (net als ik was) alleen maar geinteresseerd bent in 'is gelijk', 'bevat', 'begint met' en 'eindigt op', dan is dit functietje misschien wel bruikbaar:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
| function FindString(ASearch, AString: string): boolean;
{
Case insensitive search in a string.
ASearch can start and/or end with a '*' as a wildcard.
'ABCD' -> ASearch matches AString.
'ABCD*' -> AString starts with ASearch (without the asterix).
'*ABCD' -> AString ends with ASearch.
'*ABCD*' -> AString contains ASearch.
}
var
bAtBegin, bAtEnd: boolean;
begin
Result := False;
if (ASearch = '*') or (ASearch = '**') then
Result := True
else if AString > '' then begin
bAtBegin := (ASearch[1] <> '*');
bAtEnd := (ASearch[Length(ASearch)] <> '*');
// strip leading and trailing asterixes
if (Length(ASearch) > 0) and (ASearch[1] = '*') then
ASearch := Copy(ASearch, 2, Length(ASearch) - 1);
if (Length(ASearch) > 0) and (ASearch[Length(ASearch)] = '*') then
ASearch := Copy(ASearch, 1, Length(ASearch) - 1);
if Length(AString) < Length(ASearch) then Exit;
if bAtBegin and bAtEnd then
// whole word match
Result := (AnsiCompareText(ASearch, AString) = 0)
else begin
if bAtBegin then
// at beginning of string
Result := (AnsiCompareText(ASearch, Copy(AString, 1, Length(ASearch))) = 0)
else if bAtEnd then
// at end of string
Result := (AnsiCompareText(ASearch, Copy(AString, Length(AString) - Length(ASearch) + 1,
Length(ASearch))) = 0)
else
// somewhere in string
Result := Pos(UpperCase(ASearch), UpperCase(AString)) > 0;
end;
end;
end; |
Verwijderd
Ik heb die code uit die link die ik gaf wat verbeterd, en volgens mij doet ie het nog 
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
| function IsSame(const S, WildCard: string; const CaseSensitive: Boolean):
Boolean;
function SameName(P, WildCard: PChar): Boolean;
begin
Result := True;
while Result and (P^ <> #0) and (WildCard^ <> #0) do
case WildCard^ of
'?':
begin
Inc(P);
Inc(WildCard);
end;
'*':
begin
Inc(WildCard);
if WildCard^ <> #0 then
begin
while (P^ <> #0) and not SameName(P, WildCard) do
Inc(P);
if P^ = #0 then
Result := False
else
begin
while P^ <> #0 do
Inc(P);
while WildCard^ <> #0 do
Inc(WildCard);
end;
end
else
while P^ <> #0 do
Inc(P);
end
else
begin
Result := P^ = WildCard^;
if Result then
begin
Inc(P);
Inc(WildCard);
end;
end;
end;
if Result then
while WildCard^ = '*' do
Inc(WildCard);
Result := Result and (P^ = #0) and (WildCard^ = #0);
end;
begin
if CaseSensitive then
Result := SameName(PChar(UpperCase(S)), PChar(UpperCase(WildCard)))
else
Result := SameName(PChar(S), PChar(WildCard));
end; |
Verwijderd
Nadeel bij PChars en recursie is dat je 12x moet lezen voor je snapt wat er staat, maar volgens mij moet 'ie 't ook nog doen. Al ben ik er nog niet zeker van wat er gebeurt wanneer je een '*' midden in een zoekstring zet...Op dinsdag 04 december 2001 21:32 schreef DiFool het volgende:
Ik heb die code uit die link die ik gaf wat verbeterd, en volgens mij doet ie het nog
Zoeken we nog uit.
Verwijderd
Ik vind PChar's wel makkelijk werken met zoeken in strings enz. Vooral door de Inc(P) en de laatste #0 in een string.
Recursie is meestal niet zo moeilijk om te zien. Het volgt gewoon een inductief bewijs.
Dus in dit geval berekent IsSame of string met lengte n gelijk is aan een wildcard. In de functie ga je ervan uit [en kun je ervan uitgaan] dat de functie IsSame klopt voor strings met lengte n-1. Je moet dus zorgen dat de functie klopt voor strings met lengte n, maar je kunt gebruik maken van IsSame voor strings met lengte n-1. In dit geval doe je dat door te kijken naar de eerste char van de string; bij een char anders dan * kun je die skippen en kun je de functie IsSame weer aanroepen. Bij * moet je iets meer doen...
Nu ik dit zo opschrijf bedenk ik me dat die while-loop niet echt nodig is, omdat je daarvoor ook recursie kan gebruiken...
[edit: en wel zo]
Recursie is meestal niet zo moeilijk om te zien. Het volgt gewoon een inductief bewijs.
Dus in dit geval berekent IsSame of string met lengte n gelijk is aan een wildcard. In de functie ga je ervan uit [en kun je ervan uitgaan] dat de functie IsSame klopt voor strings met lengte n-1. Je moet dus zorgen dat de functie klopt voor strings met lengte n, maar je kunt gebruik maken van IsSame voor strings met lengte n-1. In dit geval doe je dat door te kijken naar de eerste char van de string; bij een char anders dan * kun je die skippen en kun je de functie IsSame weer aanroepen. Bij * moet je iets meer doen...
Nu ik dit zo opschrijf bedenk ik me dat die while-loop niet echt nodig is, omdat je daarvoor ook recursie kan gebruiken...
[edit: en wel zo]
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
| function SameName(P, WildCard: PChar): Boolean;
begin
{ Is P een lege string? }
if P^ = #0 then
begin
{ Zo ja, dan is P gelijk aan de WildCard als die leeg
is of uit alleen maar *'tjes bestaat }
while WildCard^ = '*' do
Inc(WildCard);
Result := WildCard^ = #0;
end
else
{ P is niet de lege string, wat is de eerste char van
de WildCard string }
case WildCard^ of
'?':
{ Bij een ? doet het er niet toe wat de eerste char
van P is dus is het resultaat gelijk aan ... of
andersom: als string P' gelijk is aan de wildcard
W' dan is Ch + P' gelijk aan '?' + W' met Ch een
willekeurige char.}
Result := SameName(P + 1, WildCard + 1);
'*':
begin
Inc(WildCard);
{ Is WildCard alleen maar '*'? }
if WildCard^ <> #0 then
begin
{ We kunnen een willekeurig aantal eerste tekens
uit P skippen; als die string gelijk is aan de
WildCard zonder de eerste * dan is P gelijk
aan de WildCard string met * , of andersom:
als P' gelijk is aan W' dan is P'' + P' gelijk
aan '*' + W' met P'' een willekeurige string}
while (P^ <> #0) and not SameName(P, WildCard) do
Inc(P);
Result := P^ <> #0;
end
else
{ WildCard = '*', dan is P altijd gelijk aan
WildCard }
Result := True;
end
else
{ De eerste char van WildCard is niet ? of *, dan is
WildCard gelijk aan P, als de eerste tekens gelijk
zijn, én als WildCard zonder de eerste char en P
zonder de eerste char gelijk zijn.
[WildCard kan ook de lege string zijn dan is
P^ <> WildCard^ omdat P^ <> #0] }
Result := (P^ = WildCard^) and SameName(P + 1, WildCard + 1);
end;
end; |
Verwijderd
Ik ben benieuwd!Op dinsdag 04 december 2001 23:48 schreef DiFool het volgende:
Nu ik dit zo opschrijf bedenk ik me dat die while-loop niet echt nodig is, omdat je daarvoor ook recursie kan gebruiken...
En ondertussen zou 't misschien voor de oplettende meelezertjes ook niet zoveel kwaad kunnen om zo hier en daar een commentaarregeltje in te lassen?
Het is alleen de vraag of dat efficienter is. (qua snelheid, en geheugengebruik (stack))Op dinsdag 04 december 2001 23:48 schreef DiFool het volgende:
Nu ik dit zo opschrijf bedenk ik me dat die while-loop niet echt nodig is, omdat je daarvoor ook recursie kan gebruiken...
Waarom het wiel opnieuw uitvinden? Kijk eens naar TMask:
Er staat wel 'file mask', maar je kan het natuurlijk ook gewoon voor strings gebruiken.TMask allows the comparison of strings containing wildcards to a file mask.
Unit
Masks
Description
Use TMask to determine if a string matches the format described by a mask. The mask contains literal characters, wildcards that can match any character, and sets that match a single character that is included in the set.
Note:Do not confuse TMask with the EditMask of a field or masked edit object. While both are used for comparing strings to a symbolic description of valid values, the special mask symbols and matching rules are completely different.
Pagina: 1