We help IT Professionals succeed at work.

Delphi2010: How to split string which contains space and " "

wantime
wantime asked
on
7,394 Views
Last Modified: 2012-05-11
hi all,

i have a string as followed:

Test01:"C:\with a space\anything_here"  Test02:"C:\with a space\with a space\anything_here"  Test03:C:\without\a\space

how do i split it into a array which contains following three element:
Test01:"C:\with a space\anything_here"
Test02:"C:\with a space\with a space\anything_here"
Test03:C:\without\a\space

i have tried to split the string, but i get just following parts:
Test01:"C:\with
a
space\anything_here"

any suggestion is appreciate. I would like to use " " and blank space to split the string.
thanks,

wantime
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    Edit2: TEdit;
    Edit3: TEdit;
    Edit4: TEdit;
    procedure Button1Click(Sender: TObject);
    procedure Split(Delimiter: Char; Str: string; ListOfStrings: TStrings) ;
  private

  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  commands: TStringList;
begin
  commands := TStringList.Create;
  Split(' ', Edit1.Text, commands) ;
  Edit2.Text := commands[0];
  Edit3.Text := commands[1];
  Edit4.Text := commands[2];
end;

procedure TForm1.Split(Delimiter: Char; Str: string; ListOfStrings: TStrings) ;
begin
   ListOfStrings.Clear;
   ListOfStrings.Delimiter     := Delimiter;
   ListOfStrings.DelimitedText := Str;
end;


end.

Open in new window

Comment
Watch Question

Ephraim WangoyaSoftware Engineer
CERTIFIED EXPERT

Commented:
try this
procedure TForm1.Button1Click(Sender: TObject);
var
  commands: TStringList;
begin
  commands := TStringList.Create;
  Split(Edit1.Text, commands) ;
  Edit2.Text := commands[0];
  Edit3.Text := commands[1];
  Edit4.Text := commands[2];
  commands.Free;
end

procedure TForm1.Split(Str: string; ListOfStrings: TStrings) ;
var
  temp: string;
  I: integer;
begin
  ListOfStrings.Clear;
  ListOfStrings.Delimiter := ',';
  ListOfStrings.StrictDelimiter := True;
  ListOfStrings.QuoteChar := '"';
  ListOfStrings.DelimitedText := Str;

  temp := StringReplace(Str, 'Test', ',Test', [rfReplaceAll]);
  if temp[1] = ',' then
    temp[1] := ' ';

  ListOfStrings.DelimitedText := Trim(temp);
end;

Open in new window

Ephraim WangoyaSoftware Engineer
CERTIFIED EXPERT

Commented:
Sorry, I assigned it twice
procedure TForm1.Button1Click(Sender: TObject);
var
  commands: TStringList;
begin
  commands := TStringList.Create;
  Split(Edit1.Text, commands) ;
  Edit2.Text := commands[0];
  Edit3.Text := commands[1];
  Edit4.Text := commands[2];
  commands.Free;
end

procedure TForm1.Split(Str: string; ListOfStrings: TStrings) ;
var
  temp: string;
  I: integer;
begin
  ListOfStrings.Clear;
  ListOfStrings.Delimiter := ',';
  ListOfStrings.StrictDelimiter := True;
  ListOfStrings.QuoteChar := '"';

  temp := StringReplace(Trim(Str), 'Test', ',Test', [rfReplaceAll]);
  if temp[1] = ',' then
    temp[1] := ' ';

  ListOfStrings.DelimitedText := Trim(temp);
end;

Open in new window

CERTIFIED EXPERT
Top Expert 2011

Commented:
Is your format constant? Is it always going to be Test01, Test02, Test03,...etc?
uses StrUtils;

procedure TForm1.Button1Click(Sender: TObject);
var
  strlst:TStrings;
  Str:String;
  i:integer;
begin
  str:='Test01:"C:\with a space\anything_here"  Test02:"C:\with a space\with a space\anything_here"  Test03:C:\without\a\space';
  strlst:=TStringlist.Create;
  i:=2;

  repeat
    strlst.Add(copy(str,1,pos('Test'+Format('%.2d', [i])+':',str)-3));
    delete(str,1,pos('Test'+Format('%.2d', [i])+':',str)-1);
    inc(i);
  until posex('Test',str,3) <= 0;

  strlst.Add(copy(str,1,length(str)));
  delete(str,1,length(str));

  showmessage(strlst.Text);
  strlst.Free;
end;

Open in new window

Geert GOracle dba
CERTIFIED EXPERT
Top Expert 2009

Commented:
use a different delimiter
do not use space as delimiter

this is same as if somebody asks you to count words in a document when somebody else has put a space between each 2 letters
you will ask them to remove extra spaces or use something else to delimit by
Ephraim WangoyaSoftware Engineer
CERTIFIED EXPERT

Commented:

If you will not have an identifier such as "TestX" in your examples, then use a proper delimiter as Geert mentioned above
You could use a semicolon and set StrictDelimiter to True
aikimarkSocial distance; Wear a mask; Don't touch your face; Wash your hands for 20 seconds
CERTIFIED EXPERT
Top Expert 2014

Commented:
1. replace all '" Test' with '"^Test' and store the resulting string in a TStringList
2. use the .DelimitedText property of the TStringList with a '^' character as the delimiter, placing the result in another TStringList variable.

Author

Commented:
thank you for your answer.

as i mentioned, I would like to use " " and blank space to split the string.

"Test" is just a example, they can also be different. just like:

X:"C:\with a space\anything_here"  Y:"C:\with a space\with a space\anything_here"  Z:C:\without\a\space

the thing i am sure it that between each block there exist a blank. If this block has space in it, symbol " " will then be used.

Author

Commented:
btw, symbol " " will be used, only if there are space in block. If there is no space in the block, " " will not be used.

first and second space has blank, so " " is used.

X:"C:\with a space\anything_here"  Y:"C:\with a space\with a space\anything_here"

the third one doesn't has space , so it looks like Z:C:\without\a\space

if there is a method to make the block which has space as a unit, then the whole string should be possible to be splited by using space as delimiter.
Geert GOracle dba
CERTIFIED EXPERT
Top Expert 2009

Commented:
using StrictDelimiter is the easiest

how do you fill up your stringlist  ?

function Test: string;
var X, Y: TStrings;
begin
  X := TStringList.Create;
  Y := TStringList.Create;
  try
    X.Delimiter := ' ';
    Y.Delimiter := ' ';
    X.StrictDelimiter := True;
    Y.StrictDelimiter := True;
    X.Add('test 1');
    X.Add('test 2');
    Y.Add(X.DelimitedText);
    X.Clear;
    X.Add('test 3');
    X.Add('test 4);
    Y.Add(X.DelimitedText);
    Result := Y.DelimitedText;
  finally
    Y.Free;
    X.Free;
  end;
end;
CERTIFIED EXPERT
Top Expert 2011
Commented:
Unlock this solution and get a sample of our free trial.
(No credit card required)
UNLOCK SOLUTION
Geert GOracle dba
CERTIFIED EXPERT
Top Expert 2009
Commented:
Unlock this solution and get a sample of our free trial.
(No credit card required)
UNLOCK SOLUTION
Geert GOracle dba
CERTIFIED EXPERT
Top Expert 2009

Commented:
forgot to post the output:
 
Memo1
Result of buildstring: 
"""TEST1=C:\with a space\anything_here"" ""TEST2=C:\with a space\with a space\anything_here"" TEST3=C:\without\a\space" """TEST4=C:\with a space\anything_here"" ""TEST5=C:\with a space\with a space\anything_here"" TEST6=C:\without\a\space"
Result of split string
TEST1=C:\with a space\anything_here
TEST2=C:\with a space\with a space\anything_here
TEST3=C:\without\a\space
TEST4=C:\with a space\anything_here
TEST5=C:\with a space\with a space\anything_here
TEST6=C:\without\a\space
Extracting specific values : 
TEST1 = "C:\with a space\anything_here"

Open in new window

Author

Commented:
sorry, i should explain my question more clear.

the string which need to be splited is not constant, but they have a format like followed:

Format I:

[A-Z][:]["][A-Z and space]["]

Format II:

[A-Z][:][A-Z]

that means, "Test01,Test02, Test03" and "X, Y, Z" that i mentioned above is just a example, the length of the word changed. The background info for this question are followed: In a text field one could input differnt Commands, these Commands is seperated by space. If Command contains space, Format I will be used, if not, Format II will be used. The format is there and i could not change it. what  I need to resolve is to splite the whole string into differnt rows/block like i mentioned before. (after the string is splited, an application will be called to execute each Command. But this is another topic which we don't need to discuss here.)
aikimarkSocial distance; Wear a mask; Don't touch your face; Wash your hands for 20 seconds
CERTIFIED EXPERT
Top Expert 2014

Commented:
@Delphi experts

Since you're working with paths, it is possible for a path to contain two consecutive spaces (or more) and still be a legal path.

You should probably test the possibility of the no-spaces path not being the last one in the input string.

======
@wantime

Will you support UNC paths or will you always have a drive letter?

Path names can contain characters other than A-Z.  Your pattern definition is incomplete.
Geert GOracle dba
CERTIFIED EXPERT
Top Expert 2009

Commented:
i'm lost, you are asking something completely different now ?

if you care to be precise with your question ...
you will get an acurate and precise answer

this is making it difficult to follow !
aikimarkSocial distance; Wear a mask; Don't touch your face; Wash your hands for 20 seconds
CERTIFIED EXPERT
Top Expert 2014
Commented:
Unlock this solution and get a sample of our free trial.
(No credit card required)
UNLOCK SOLUTION
Ephraim WangoyaSoftware Engineer
CERTIFIED EXPERT
Commented:
Unlock this solution and get a sample of our free trial.
(No credit card required)
UNLOCK SOLUTION

Author

Commented:
At the begin i was not sure, what the format should be look like. your suggestion have already help to resolve the problem, after i redefine the format in my codes.
Unlock the solution to this question.
Thanks for using Experts Exchange.

Please provide your email to receive a sample view!

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.