Solved

Comma-seperated sub string extract

Posted on 1999-01-08
12
663 Views
Last Modified: 2010-04-06
I have a string containing comma-seperated values:

1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20

i.e. 20 values with commas seprating them (18 commas)

This string we will call MainString

I want a function will the following call

ExtractSubString(MainString, Start, Finish): string
where
 MainString is the string above
 Start is the first value to extract
 Finish is the last value to extract

ExtractSubString returns a string containing the substring

For example, I call ExtractSubString with the following parameters:

MainString,1,20
the returned substring looks like this:
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20

or
MainString,5,20
the returned substring looks like this:
5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20

or

MainString,5,15
the returned substring looks like this:
5,6,7,8,9,10,11,12,13,14,15

or

MainString,19,20
the returned substring looks like this:
19,20

i.e. I want to keep the commas intact

A function that does these three examples perfectly wins the points. It must also be fast. i don't need to know the actul values at any point so you can keep the whole thing as strings.

Cheers

Ian

0
Comment
Question by:iwatkins
  • 5
  • 3
  • 2
  • +2
12 Comments
 

Author Comment

by:iwatkins
ID: 1355252
Adjusted points to 400
0
 
LVL 3

Accepted Solution

by:
Ronald Buster earned 400 total points
ID: 1355253
Hi,

Here the solution for your problem, tested it on your 3 examples and it worked.

Enjoy

Regards,

Cono


<---CUT HERE----->

function ExtractSubString(Value : String; pos1,pos2 : integer ) : string;
var s1,s2 : string;
begin
  Result := '';

  s1 := Trim(Value);
  while pos(',',s1) > 0 do
    begin
      s2 := copy(s1,1,pos(',',s1)-1);
      if (StrToInt(s2) >= pos1) and (StrToInt(s2) <= pos2) then
        begin
          Result := Result + s2 + ',';
        end;
      delete(s1,1,pos(',',s1));
    end;

  if (StrToInt(s1) >= pos1) and (StrToInt(s1) <= pos2) then
    begin
      Result := Result + s1;
    end;
end;

<---CUT HERE----->
0
 
LVL 5

Expert Comment

by:heathprovost
ID: 1355254
Here is my version

function ExtractSubString(MainString: String; Start, Finish: integer): string;
var
  TempString: String;
  CommaCount: integer;
  StartPos, EndPos: integer;
  StringLength: integer;
begin
  TempString := ',' + MainString + ',';
  StringLength := Length(TempString);
  CommaCount := 0;
  StartPos := 1;
  Repeat
    if TempString[StartPos] = ',' then Inc(CommaCount);
    Inc(StartPos);
    if StartPos = StringLength then
    begin
      Result := 'ERROR';
      Exit;
    end;
  Until CommaCount = Start;
  CommaCount := 0;
  EndPos := StartPos + 1;
  Repeat
    if TempString[EndPos] = ',' then Inc(CommaCount);
    Inc(EndPos);
    if EndPos = StringLength then
    begin
      Result := 'ERROR';
      Exit;
    end;
  Until CommaCount = Finish - Start + 1;
  Result := Copy(TempString, StartPos, EndPos - StartPos - 1);
end;

Heath
0
Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 5

Expert Comment

by:heathprovost
ID: 1355255
Condensed a bit


function ExtractSubString(MainString: String; Start, Finish: integer): string;
var
  TempString: String;
  CommaCount: integer;
  StartPos, EndPos: integer;
  StringLength: integer;
begin
  Result := 'ERROR';
  TempString := ',' + MainString + ',';
  StringLength := Length(TempString);
  CommaCount := 0;
  StartPos := 1;
  Repeat
    if TempString[StartPos] = ',' then Inc(CommaCount);
    Inc(StartPos);
    if StartPos = StringLength then
      Exit;
  Until CommaCount = Start;
  CommaCount := 0;
  EndPos := StartPos + 1;
  Repeat
    if TempString[EndPos] = ',' then Inc(CommaCount);
    Inc(EndPos);
    if EndPos = StringLength then
      Exit;
    end;
  Until CommaCount = Finish - Start + 1;
  Result := Copy(TempString, StartPos, EndPos - StartPos - 1);
end;


Heath
0
 
LVL 5

Expert Comment

by:heathprovost
ID: 1355256
The best I can do.....(Fixed bug in error code and condensed a bit more)

function ExtractSubString(MainString: String; Start, Finish: integer): string;
var
  TempString: String;
  CommaCount: integer;
  StartPos, EndPos: integer;
  StringLength: integer;
begin
  Result := 'ERROR';
  TempString := ',' + MainString + ',';
  StringLength := Length(TempString);
  CommaCount := 0;
  StartPos := 1;
  Repeat
    if StartPos > StringLength then Exit;
    if TempString[StartPos] = ',' then Inc(CommaCount);
    Inc(StartPos);
  Until CommaCount = Start;
  CommaCount := 0;
  EndPos := StartPos + 1;
  Repeat
    if EndPos > StringLength then Exit;
    if TempString[EndPos] = ',' then Inc(CommaCount);
    Inc(EndPos);
  Until CommaCount = Finish - Start + 1;
  Result := Copy(TempString, StartPos, EndPos - StartPos - 1);
end;

Heath
0
 

Author Comment

by:iwatkins
ID: 1355257
Easy when you know how !

Things are clear, and it works.

Cheers

Cono
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 1355258
hi,

a other way, with strings


function selectpart(source, Starting, Ending : String) : String;
begin
  If pos(Starting,source) = 0 then
    result := 'Start not found'
  else
    If pos(Ending,source) = 0 then
      result := 'End not found'
    else
      If pos(Ending,source) < pos(Starting,source) then
        result := 'End before Start'
      else
        result := copy(source,pos(starting,source),pos(Ending,source)+Length(Ending)-pos(starting,source));
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  edit4.text := SelectPart(edit1.text,edit2.text,edit3.text);
end;


meikl
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 1355259
Hi,

it seems i am a little late for this q

meikl
0
 
LVL 5

Expert Comment

by:heathprovost
ID: 1355260
No offense intended, But his cono's functin does NOT do what you asked.  for example:

ExtractSubString('1,2,3,4,5,6,7,8,9,0', 1, 9) returns

"1,2,3,4,5,6,7,8,9," not "1,2,3,4,5,6,7,8,9"

also

ExtractSubString('100,200,300,400,500,600,700,800,900,1000', 1, 9) returns

NOTHING!

I wrote my function to be generic, as in ALL input in the format you specified returns valid results.  I think you should be more careful evaluating things next time.

Heath
0
 
LVL 3

Expert Comment

by:Matvey
ID: 1355261
Ooooh, man, I'm a bit late... Do you want to see what a beauty I made? Well, I have nobody else to show this to, so here it is:
________________________________________________________________
function ExtractSubString(MainString: string; Start, Finish: integer): string;
var
  AP: TParser;
  SS: TStringStream;
  CI, StartPos, EndPos: integer;
begin
  SS := TStringStream.Create(MainString);
  AP := TParser.Create(SS);
  CI := 1;
  with AP do begin
    repeat
      if Token = ',' then begin inc(CI); NextToken; end;
      if CI <= Start then StartPos := SourcePos;
    until (NextToken = #0) or (CI >= Finish);
    EndPos := SourcePos;
  end;
  Result := Copy(MainString, StartPos+1, EndPos-StartPos);
  AP.Free;
  SS.Free;
end;
________________________________________________________________
0
 
LVL 5

Expert Comment

by:heathprovost
ID: 1355262
Hey Matvey, that one real nice :)
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 1355263
Matvey,

really late, but a tricky way

meikl
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
This video shows how to quickly and easily add an email signature for all users on Exchange 2016. The resulting signature is applied on a server level by Exchange Online. The email signature template has been downloaded from: www.mail-signatures…
Email security requires an ever evolving service that stays up to date with counter-evolving threats. The Email Laundry perform Research and Development to ensure their email security service evolves faster than cyber criminals. We apply our Threat…

830 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question