Recent

Author Topic: Find unknown string in a string  (Read 10071 times)

Zath

  • Sr. Member
  • ****
  • Posts: 391
Re: Find unknown string in a string
« Reply #15 on: June 17, 2015, 06:01:12 pm »
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+}

interface

uses
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.

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.


Zath

  • Sr. Member
  • ****
  • Posts: 391
Re: Find unknown string in a string
« Reply #16 on: June 17, 2015, 06:24:03 pm »
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.1
blahblah
True
sa

This looks lovely and simple but how do I change it from a console application to using a form ?

sfeinst

  • Full Member
  • ***
  • Posts: 237
Re: Find unknown string in a string
« Reply #17 on: June 17, 2015, 07:02:45 pm »
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.

I'm using Lazarus 1.4 on Windows.  What version are you using?

Zath

  • Sr. Member
  • ****
  • Posts: 391
Re: Find unknown string in a string
« Reply #18 on: June 17, 2015, 07:28:31 pm »
Sorry, I should have put that on.
I'm using 1.4RC3 (2.6.4) on Win7.

sfeinst

  • Full Member
  • ***
  • Posts: 237
Re: Find unknown string in a string
« Reply #19 on: June 17, 2015, 07:56:40 pm »
If you just copied code and pasted, you may be missing the form information, so here is the full project.  Some code updated to handle the doubled-up quotes that probably are not in your data, but included anyway.

Zath

  • Sr. Member
  • ****
  • Posts: 391
Re: Find unknown string in a string
« Reply #20 on: June 17, 2015, 09:33:16 pm »
That works fine, thanks.

Now I need to study it a bit to see what's going on.

I also liked the look of the console code that was posted.

Thanks to everyone who responded.

CM630

  • Hero Member
  • *****
  • Posts: 1356
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Find unknown string in a string
« Reply #21 on: June 18, 2015, 10:15:47 pm »
According to MSDN if a value contains both ' and " then whichever is used to quote...
Could  tstringlist be instructed to split only until the third semicolon?
If so and if password is the only key, which can contain " and ; I could simply reorder
Provider=SQLOLEDB.1;Password=blahblah;'Persist Security Info=True;User ID=sa
to  Provider=SQLOLEDB.1;Persist Security Info=True;User ID=sa;Password=can_contain_absolutely_any_character
Лазар 4,0 32 bit (sometimes 64 bit); FPC3,2,2

 

TinyPortal © 2005-2018