Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Wildcard search in a string.

958 views
Skip to first unread message

Sjorsj

unread,
Jun 27, 2008, 10:36:48 AM6/27/08
to
Is there some standard function in Delphi to search with a wild card in
another string?

Like searching for '?yyy*' in 'HyyyMupietumpie', answer true.


Caleb Hattingh

unread,
Jun 27, 2008, 11:06:27 AM6/27/08
to

TPerlRegex works well for me so far:

http://www.regular-expressions.info/delphi.html

It is very easy to install this component and add it to form to get
instant regex support. In your case, and assuming you call your component
MyRegex:

{pseudo warning: may not compile}
const
MatchThis = '?yyy';
SearchSpace = 'HyyyMupietumpie';
begin
MyRegex.Regex := MatchThis;
MyRegex.Subject := SearchSpace;
GotMatch := MyRegex.Match;
while GotMatch do {Search through the whole string, report each match}
begin
MessageBox('The expression that matched was ' +
MyRegex.MatchedExpression);
GotMatch := MyRegex.MatchAgain;
end;
end;

The component has everything you would expect, such as groups, negative
lookahead and lookbehind, and so on.


Sjorsj

unread,
Jun 27, 2008, 11:21:55 AM6/27/08
to

"Caleb Hattingh" <caleb.h...@no.spam.gmail.com> wrote

> TPerlRegex works well for me so far:

Ok, I used Regex in another program too, and if I introduce the Regex in my
program, I might use it for more complex things in the future.

There is no, simple, build in function for this? Regex is a bit like
shooting with a cannon on a mosquito here, and I probably get an agry boss
if I add 'unnecesarry complicated stuff'.

By the way, I am using Delphi 5, it's quite an old program.


John Jarrett

unread,
Jun 27, 2008, 12:04:55 PM6/27/08
to
Try:

function MemPos(const Filename, TextToFind: string; iFrom: cardinal = 0;
CaseSensitive: boolean = False): int64;
var
buffer : string;
len : integer;
MS : TMemoryStream;
charsA, charsB : set of char;
p, pEnd : PChar;
begin
result := -1;
if (TextToFind <> '') and FileExists(Filename) then
begin
len := Length(TextToFind);
SetLength(buffer, len);
if CaseSensitive then
begin
charsA := [TextToFind[1]];
charsB := [TextToFind[len]];
end
else
begin
charsA := [ AnsiLowerCase(TextToFind)[1],
AnsiUpperCase(TextToFind)[1] ];
charsB := [ AnsiLowerCase(TextToFind)[len],
AnsiUpperCase(TextToFind)[len]];
end;
MS := TMemoryStream.Create;
try
MS.LoadFromFile(Filename);
if (len <= MS.Size) and (iFrom <= (MS.Size - len) + 1) then
begin
p := MS.Memory;
pEnd := p;
Inc(p, iFrom);
Inc(pEnd, (MS.Size - len) + 1);
while (p <= pEnd) and (result < 0)
do
begin
if (p^ in charsA) and ((p +len -1)^ in charsB) then
begin
MoveMemory(@buffer[1], p, len);
if (CaseSensitive and (AnsiCompareStr(TextToFind, buffer) = 0))
or
(AnsiCompareText(TextToFind, buffer) = 0) then
result := p -MS.Memory;
end;
Inc(p);
end;
end;
finally
MS.Free;
end;
end;
end;

John

"Sjorsj" <sa...@ingcarlease.nl> wrote in message
news:4864faeb$1...@newsgroups.borland.com...

Remy Lebeau (TeamB)

unread,
Jun 27, 2008, 12:10:57 PM6/27/08
to

"Sjorsj" <sa...@ingcarlease.nl> wrote in message
news:4865...@newsgroups.borland.com...

> There is no, simple, build in function for this?

The closest thing available is the MatchesMask() function in the Masks unit.

uses
Masks;

if MatchesMask('HyyyMupietumpie', '?yyy*') then
...


Gambit


Ken White

unread,
Jun 27, 2008, 1:09:55 PM6/27/08
to

For Pete's sake! I can't believe all of the convoluted answers
you've gotten so far! :-)

Since "a wildcard" doesn't matter at all, and all you care
about is "Does 'yyy' exist anywhere in 'HyyyMupietumpie'?",
the easiest way is the Pos() function:

if Pos('yyy', 'HyyyMupietumpie') > 0 then
// In this case, the result of Pos() would be
// 2, meaning that 'yyy' was found.

You might also see PosEx(), which allows you to find the first
and subsequent occurrences of <substring> in <string>.

HTH,

Ken

Q Correll

unread,
Jun 27, 2008, 1:28:21 PM6/27/08
to
Sjorsj,

| Is there some standard function in Delphi to search with a wild card
| in another string?

Reading ahead a bit... why not just use pos() function to locate the
substr? Then if the return is > 0 it's found. That's what I do for
simple substr searches instead of complex RegEx cra... stuff. ;-)

--
Q

06/27/2008 10:25:34

XanaNews Version 1.17.5.7 [Q's Salutation mod]

Q Correll

unread,
Jun 27, 2008, 1:28:50 PM6/27/08
to
Sjorsj,

| By the way, I am using Delphi 5, it's quite an old program.

It has the pos() function. <g>

--
Q

06/27/2008 10:28:34

Marc Rohloff [TeamB]

unread,
Jun 27, 2008, 1:46:53 PM6/27/08
to
On 27 Jun 2008 10:09:55 -0700, Ken White wrote:

> if Pos('yyy', 'HyyyMupietumpie') > 0 then
> // In this case, the result of Pos() would be
> // 2, meaning that 'yyy' was found.

With this '?yyy' would match 'yyyHupieTumpie' which it shouldn't but
it is easy enough to fix:

if Pos('yyy', 'yyyMupietumpie') > 1 then

--
Marc Rohloff [TeamB]
marc -at- marc rohloff -dot- com

Dave White

unread,
Jun 27, 2008, 3:29:50 PM6/27/08
to
"Marc Rohloff [TeamB]" <ma...@nospam.marcrohloff.com> wrote in message
news:1be0xqjf...@dlg.marcrohloff.com...

> On 27 Jun 2008 10:09:55 -0700, Ken White wrote:
>
>> if Pos('yyy', 'HyyyMupietumpie') > 0 then
>> // In this case, the result of Pos() would be
>> // 2, meaning that 'yyy' was found.
>
> With this '?yyy' would match 'yyyHupieTumpie' which it shouldn't but
> it is easy enough to fix:
>
> if Pos('yyy', 'yyyMupietumpie') > 1 then
>

And although this will work well when you know the wildcard string in
advance, it'll fail if you have the user enter the string via an edit box or
such. The only failsafe way is to use some form of reg expression
evaluation, or the Masks unit, as Gambit pointed out.

Dave White


Marc Rohloff [TeamB]

unread,
Jun 27, 2008, 5:47:44 PM6/27/08
to
On Fri, 27 Jun 2008 14:29:50 -0500, Dave White wrote:

> The only failsafe way is to use some form of reg expression

Except that ?yyy is not a regular expression.

Q Correll

unread,
Jun 27, 2008, 7:59:03 PM6/27/08
to
Ken,

| the easiest way is the Pos() function:

That's what I also typed. <g>

--
Q

06/27/2008 16:58:41

Caleb Hattingh

unread,
Jun 28, 2008, 6:07:35 PM6/28/08
to
On Fri, 27 Jun 2008 17:21:55 +0200, Sjorsj <sa...@ingcarlease.nl> wrote:

> "Caleb Hattingh" <caleb.h...@no.spam.gmail.com> wrote
>
>> TPerlRegex works well for me so far:
>
> Ok, I used Regex in another program too, and if I introduce the Regex in
> my
> program, I might use it for more complex things in the future.
>
> There is no, simple, build in function for this? Regex is a bit like
> shooting with a cannon on a mosquito here, and I probably get an agry
> boss
> if I add 'unnecesarry complicated stuff'.

Ignorance breeds fear. That is exactly why I took the time to type that
example in my previous post for you. It all sounds very complicated
until you see such an example (8 lines of string matching logic?).

I would be surprised if your boss would consider such a code segment to be
very complicated. Integrating the support is just installing a component
and dropping it on a form. It really couldn't be simpler, and as you
pointed out, the rest of regex functionality lies waiting for you if you
happen to have a more complicated query.

> By the way, I am using Delphi 5, it's quite an old program.

Good point; I don't know whether TPerlRegex works in D5, and I'm not going
to look it up for you :)

Good luck
Caleb

Felix Saphir

unread,
Jun 28, 2008, 6:12:52 PM6/28/08
to
Caleb Hattingh wrote:
> On Fri, 27 Jun 2008 17:21:55 +0200, Sjorsj <sa...@ingcarlease.nl>
> wrote:
>> "Caleb Hattingh" <caleb.h...@no.spam.gmail.com> wrote
>>> TPerlRegex works well for me so far:
>>>
>> By the way, I am using Delphi 5, it's quite an old program.
>>
> Good point; I don't know whether TPerlRegex works in D5, and I'm not
> going to look it up for you :)

It does, I'm using it quite a lot :)

Felix

Caleb Hattingh

unread,
Jun 28, 2008, 6:38:58 PM6/28/08
to
On Fri, 27 Jun 2008 17:21:55 +0200, Sjorsj <sa...@ingcarlease.nl> wrote:

> There is no, simple, build in function for this? Regex is a bit like
> shooting with a cannon on a mosquito here, and I probably get an agry
> boss
> if I add 'unnecesarry complicated stuff'.

And another thing: string-matching, in the general case, is a Solved
Problem, and the solution is regex (PyParsing notwithstanding). For
specific subsets of matches, there are usually solutions simpler to
implement from scratch than regex would be to implement from scratch (in
this case, the Pos solutions above). However, that choice is absurd.
The actual choice is whether to implement a quick custom solution, versus
just simply calling a pre-existing regex library. There are precious few
good reasons why you would ever want to write that code yourself.

Ralf Junker - http://www.yunqa.de/delphi/

unread,
Jun 29, 2008, 4:39:10 AM6/29/08
to
"Sjorsj" <sa...@ingcarlease.nl> wrote:

The "StrMatchWild..." functions in DIUtils.pas serves your purpose. AnsiString
and WideString variants are available.

The MPL licensed DIUtils.pas is included in many of my packages like DIRegEx,
DIHtmlParser, DIFileFinder, DIUnicode.

Ralf

---
The Delphi Inspiration
http://www.yunqa.de/delphi/

Justus J.

unread,
Jun 29, 2008, 12:04:58 PM6/29/08
to
On 27/06/2008 19:46, Marc Rohloff [TeamB] wrote (amongst others) :
> On 27 Jun 2008 10:09:55 -0700, Ken White wrote:
>
>> if Pos('yyy', 'HyyyMupietumpie') > 0 then
>> // In this case, the result of Pos() would be
>> // 2, meaning that 'yyy' was found.
>
> With this '?yyy' would match 'yyyHupieTumpie' which it shouldn't but
> it is easy enough to fix:
>
> if Pos('yyy', 'yyyMupietumpie') > 1 then
>

Assuming the '?' stands for (exactly) 1 character, and the '*' for any
(0 or more), the example should read:

if (Pos('yyy', 'HyyyMupietumpie')=2) then ...

Justus

Paul Nicholls

unread,
Jun 29, 2008, 7:46:38 PM6/29/08
to
"Sjorsj" <sa...@ingcarlease.nl> wrote in message
news:4864faeb$1...@newsgroups.borland.com...

> Is there some standard function in Delphi to search with a wild card in
> another string?
>
> Like searching for '?yyy*' in 'HyyyMupietumpie', answer true.
>

Hi Sjorsj, I have some code (see below) that can do pattern matches using *
and ? characters in a string. I got it off the net ages ago.

The source parameter is the string you want to see if it matches the pattern
parameter containing 0 or more of the wild card characters above.

As an example, Matches('Hi*','Hi world') would return true.

function Matches(pattern,source: String): Boolean;
var
pSource: Array [0..255] of Char;
pPattern: Array [0..255] of Char;
function MatchPattern(element, pattern: PChar): Boolean;
function IsPatternWild(pattern: PChar): Boolean;
begin
Result := StrScan(pattern,'*') <> nil;
if not Result then Result := StrScan(pattern,'?') <> nil;
end;
begin
if 0 = StrComp(pattern,'*') then
Result := True
else if (element^ = Chr(0)) and (pattern^ <> Chr(0)) then
Result := False
else if element^ = Chr(0) then
Result := True
else begin
case pattern^ of
'*': if MatchPattern(element,@pattern[1]) then
Result := True
else
Result := MatchPattern(@element[1],pattern);
'?': Result := MatchPattern(@element[1],@pattern[1]);
else
if element^ = pattern^ then
Result := MatchPattern(@element[1],@pattern[1])
else
Result := False;
end;
end;
end;
begin
StrPCopy(pSource,source);
StrPCopy(pPattern,pattern);
Result := MatchPattern(pSource,pPattern);
end;


Sjorsj

unread,
Jun 30, 2008, 3:01:19 AM6/30/08
to

"Dave White" <n...@no.com> wrote

> And although this will work well when you know the wildcard string in
> advance, it'll fail if you have the user enter the string via an edit box
> or such.

Which is the case, and personally I'd rather go for the regex. I've got
experience in it, and it one of those nice techniques you can you in all
programming environments. My boss has to swallow it!


Sjorsj

unread,
Jun 30, 2008, 2:56:34 AM6/30/08
to

"Caleb Hattingh" <caleb.h...@no.spam.gmail.com> wrote


> Ignorance breeds fear.

Hey, I hope you mean my boss.

> Good point; I don't know whether TPerlRegex works in D5, and I'm not going
> to look it up for you :)

Actually I used a Regex component in D5 for another program already:
RegExpr.pas

TRegExpr class library
Delphi Regular Expressions

Copyright (c) 1999-2004 Andrey V. Sorokin, St.Petersburg, Russia


Sjorsj

unread,
Jun 30, 2008, 3:09:24 AM6/30/08
to

"Q Correll" <qcor...@pacNObell.net> wrote

> Reading ahead a bit... why not just use pos() function to locate the
> substr? Then if the return is > 0 it's found. That's what I do for
> simple substr searches instead of complex RegEx cra... stuff. ;-)

Because the string will be a input from the user, hence it can be

??h?*ooo-?

or even

?????i*

or whatever.

And because I do not like to use program language dependant stuff. Sorry
guys, but.... I am not a Delphi programmer. Not in the sence that I only use
Delphi for all the things I want to program anyway. I'd like to use things
that I can use in other environments too. Like Regex libs and Log4Delphi,
using that stuff I gain knowledge I can use in another environment too. So
any argument to push regex in my program is very welcome to me.


Q Correll

unread,
Jun 30, 2008, 12:09:04 PM6/30/08
to
Sjorsj,

| but.... I am not a Delphi programmer.

No comment. <g>

--
Q

06/30/2008 09:08:48

Sjorsj

unread,
Jul 1, 2008, 4:46:20 AM7/1/08
to
> Gambit :

> The closest thing available is the MatchesMask() function in the Masks
> unit.

I think this is the best solution. Thanks!


0 new messages