This is a very quick example put together. I'm sure someone can improve upon it. But it should parse the conn string without regard to order and embedded values. It assumes a proper connection string. Probably missed something though:Code: [Select]unit Unit1;{$mode objfpc}{$H+}interfaceuses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;type StrArr = Array[0..1] of string; ConnArr = Array of StrArr; { TForm1 } TForm1 = class(TForm) Button1: TButton; Edit1: TEdit; Memo1: TMemo; procedure Button1Click(Sender: TObject); private { private declarations } function SplitConn(AStr: string): ConnArr; public { public declarations } end;var Form1: TForm1;implementation{$R *.lfm}{ TForm1 }function TForm1.SplitConn(AStr: string): ConnArr;var ch: char; inval: boolean; inquote: boolean; quoteval: char; cnt: integer; start: integer; len: integer;begin inval := false; inquote := false; quoteval := ' '; cnt := 0; start := 1; len := 0; for ch in AStr do begin if not inquote then begin if (ch = '"') or (ch = '''') then begin inquote := true; quoteval := ch; Inc(start); end else if ch = '=' then begin // end of first item Inc(cnt); SetLength(Result, cnt); Result[cnt-1][0] := Copy(AStr, start, len); inval := true; start := start + len + 1; len := 0; end else if ch = ';' then begin if inval then begin // end of second item Result[cnt-1][1] := Copy(AStr, start, len); inval := false; start := start + len + 1; len := 0; end else // most likely semi after closing quote so skip past Inc(start); end else Inc(len); end else begin if quoteval = ch then begin // end of second item Result[cnt-1][1] := Copy(AStr, start, len); inval := false; start := start + len + 1; len := 0; inquote := false; quoteval := ' '; end else Inc(len); end; end;end;procedure TForm1.Button1Click(Sender: TObject);var data: ConnArr; str: string; I: integer;begin str := ''; data := SplitConn(Edit1.Text); for I := 0 to Length(data) - 1 do str := str + data[I][0] + ' has a value of ' + data[I][1] + LineEnding; Memo1.Text := str;end;end.
unit Unit1;{$mode objfpc}{$H+}interfaceuses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;type StrArr = Array[0..1] of string; ConnArr = Array of StrArr; { TForm1 } TForm1 = class(TForm) Button1: TButton; Edit1: TEdit; Memo1: TMemo; procedure Button1Click(Sender: TObject); private { private declarations } function SplitConn(AStr: string): ConnArr; public { public declarations } end;var Form1: TForm1;implementation{$R *.lfm}{ TForm1 }function TForm1.SplitConn(AStr: string): ConnArr;var ch: char; inval: boolean; inquote: boolean; quoteval: char; cnt: integer; start: integer; len: integer;begin inval := false; inquote := false; quoteval := ' '; cnt := 0; start := 1; len := 0; for ch in AStr do begin if not inquote then begin if (ch = '"') or (ch = '''') then begin inquote := true; quoteval := ch; Inc(start); end else if ch = '=' then begin // end of first item Inc(cnt); SetLength(Result, cnt); Result[cnt-1][0] := Copy(AStr, start, len); inval := true; start := start + len + 1; len := 0; end else if ch = ';' then begin if inval then begin // end of second item Result[cnt-1][1] := Copy(AStr, start, len); inval := false; start := start + len + 1; len := 0; end else // most likely semi after closing quote so skip past Inc(start); end else Inc(len); end else begin if quoteval = ch then begin // end of second item Result[cnt-1][1] := Copy(AStr, start, len); inval := false; start := start + len + 1; len := 0; inquote := false; quoteval := ' '; end else Inc(len); end; end;end;procedure TForm1.Button1Click(Sender: TObject);var data: ConnArr; str: string; I: integer;begin str := ''; data := SplitConn(Edit1.Text); for I := 0 to Length(data) - 1 do str := str + data[I][0] + ' has a value of ' + data[I][1] + LineEnding; Memo1.Text := str;end;end.
Another quick solution (among many others, as mentioned previously) is to use a TStringList to parse the text as KeyValue pairs (since you have an equal symbol, this fits perfectly):Code: [Select]program Project1;uses classes;const txt = 'Provider=SQLOLEDB.1;Password=blahblah;' + 'Persist Security Info=True;User ID=sa;';var str: TStringList;begin str := TStringList.Create; str.Delimiter:=';'; str.StrictDelimiter:=true; str.DelimitedText:= txt; writeln( str.Values['Provider'] ); writeln( str.Values['Password'] ); writeln( str.Values['Persist Security Info'] ); writeln( str.Values['User ID'] ); readln; str.Free;end. output:Code: [Select]SQLOLEDB.1blahblahTruesa
program Project1;uses classes;const txt = 'Provider=SQLOLEDB.1;Password=blahblah;' + 'Persist Security Info=True;User ID=sa;';var str: TStringList;begin str := TStringList.Create; str.Delimiter:=';'; str.StrictDelimiter:=true; str.DelimitedText:= txt; writeln( str.Values['Provider'] ); writeln( str.Values['Password'] ); writeln( str.Values['Persist Security Info'] ); writeln( str.Values['User ID'] ); readln; str.Free;end.
SQLOLEDB.1blahblahTruesa
I used your code and it builds and runs fine.However, once a click the button, I get a SIGSEGV error regardless of text entered.
According to MSDN if a value contains both ' and " then whichever is used to quote...