Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

Comma-seperated sub string extract

Posted on 1999-01-08
12
Medium Priority
?
669 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 1200 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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

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

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
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…
this video summaries big data hadoop online training demo (http://onlineitguru.com/big-data-hadoop-online-training-placement.html) , and covers basics in big data hadoop .
Is your data getting by on basic protection measures? In today’s climate of debilitating malware and ransomware—like WannaCry—that may not be enough. You need to establish more than basics, like a recovery plan that protects both data and endpoints.…

916 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