Forum > Beginners

String probelm(Solved)

<< < (2/6) > >>

jamie:
of course, you can haul in the "StrUtils" unit and have just about all you need to manipulating strings.

 it has PosEx that allows you to select your starting indexes which means you can chain on from the last PosEx search to the next.

 Also, I Believe there is a PStr function somewhere that does the same as the C version does.

Zvoni:

--- Quote from: jamie on February 25, 2023, 04:42:58 pm ---of course, you can haul in the "StrUtils" unit and have just about all you need to manipulating strings.

 it has PosEx that allows you to select your starting indexes which means you can chain on from the last PosEx search to the next.

 Also, I Believe there is a PStr function somewhere that does the same as the C version does.

--- End quote ---
I was thinking about that, too, but IIRC that unit deals with PChar‘s, so i‘m a bit wary about it

JLWest:
@Zvoni I think what you published is about right

What I'm trying to parse out of the strings is the name.

procedure AbandonSignalHandler(RtlSigNum: Integer );
procedure AddExitProc(Proc: TProcedure );
procedure Close(var f: file);
protected procedure TCustomComboBox.CloseUp virtual;
procedure ClrEol;

In each example I strip off everything before the name leaving the string to be parsed as follows:.

AbandonSignalHandler(RtlSigNum: Integer );
AddExitProc(Proc: TProcedure );
Close(var f: file);
CloseUp virtual;
ClrEol;

I first thought I could Copy2symb if I knew what the symbol was but I don't think I can.
Maybe all I need is the location of what ever the first symbol is. Then I could do a Name:=Copy(Astr,1,p);

Spector solution is working somewhat.



 

JLWest:
@Zvoni

I implemented your code example in a demo. It has a problems.

With  'procedure TCustomComboBox.CloseUp virtual;' I strip away procedure and TCustomComboBox leaving
CloseUp virtual; I'm after the name CloseUp but a sName:=Copy(sCopy,1,(a-1)); returns: CloseUp virtual. So I add a '  ' (space) to the fields array. But in the search routine it finds the ';' before the space.

const
  fields : array of string = ('(', ' = ', '; ', ':', '[', ',', ':= ', '-', ' '); a := pos(u,s);

The code is doing a position search in a string for the items in the Fields array. What would be returned is dependent of what order the items are in the array.


I can think of two ways to solve this.
1. Search the string for each item in the Fields array. When one is found add it's pos and the item in a TStringList.

8, '  '
15,;
Then iterate thru the TStringlist returning the lowest number and associated item.  Hows that for ugly? or maybe go thru the string to be searched char at a time, comparing each char with the Fields arrays items. First hit gives the position and  item.





Zvoni:
Proof of concept

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---program Project1;Uses SysUtils, Classes; Var  Delimiters:String='(|.| = |;  |:|[|,|:= |-)';          //This is not making any sense  Source1:String='procedure Erase(var f: file );';  Source2:String='protected procedure TLazLoggerLogGroupList.Remove(const AConfigName: string );'; Var  MyPos:Integer;  MyChar:String;Function CleanUp(Const ASource:String):String;Var s:String;Begin  s:=ASource.Replace(' :',':',[rfReplaceAll]);  s:=s.Replace(': ',':',[rfReplaceAll]);  s:=s.Replace(' ;',';',[rfReplaceAll]);  s:=s.Replace('; ',';',[rfReplaceAll]);  s:=s.Replace('( ','(',[rfReplaceAll]);  s:=s.Replace(' (','(',[rfReplaceAll]);  s:=s.Replace(') ',')',[rfReplaceAll]);  s:=s.Replace(' )',')',[rfReplaceAll]);  s:=s.Replace('= ','=',[rfReplaceAll]);  s:=s.Replace(' =','=',[rfReplaceAll]);  s:=s.Replace(':= ',':=',[rfReplaceAll]);  s:=s.Replace(' :=',':=',[rfReplaceAll]);  Result:=s;end; Function GetPosString(Var ASource:String;Const ADelimiters:String;Var APos:Integer):String;Var  i:Integer;  p:Integer;  MinPos:Integer;  MinChr:String;Begin  ASource:=CleanUp(ASource);  MinPos:=Length(ASource)+1;  Result:='';  MinChr:='';  For i:=1 To Length(ADelimiters) Do    Begin      p:=Pos(ADelimiters[i],ASource);      If (p>0) And (p<MinPos) Then         Begin           MinPos:=p;           MinChr:=ADelimiters[i];         end;    end;  APos:=MinPos;  Result:=MinChr;end; Function GetPosition(Var ASource:String;Const ADelimiters:String;Var APosition:Integer):String;Var  i:Integer;  p:Integer;  d:String;  MinPos:Integer;  MinChr:String;  s:Array Of String;Begin  d:=ADelimiters.Replace(' ','');        //We don't need spaces, since we're cleaning up the Source  ASource:=CleanUp(ASource);  Result:='';  MinChr:='';  MinPos:=Length(ASource)+1;             //We're setting the "Fail"-Result to Source-Length+1  s:=ADelimiters.Split('|');             //Splitting the Delimiters  For i:=Low(s) To High(s) Do            //Run through your Delimiters    Begin      p:=Pos(s[i],ASource);              //Get Position      If (p>0) And (p<MinPos) Then         begin           MinPos:=p;           MinChr:=s[i]         end;    end;  APosition:=MinPos;  Result:=MinChr;End; begin  MyChar:=GetPosition(Source1,Delimiters,MyPos);  Writeln('Char=',MyChar,' found at Pos.=',MyPos,' in cleaned up String=',Source1);  MyChar:=GetPosition(Source2,Delimiters,MyPos);  Writeln('Char=',MyChar,' found at Pos.=',MyPos,' in cleaned up String=',Source2);  MyChar:=GetPosString(Source1,'.(;',MyPos);  Writeln('Char=',MyChar,' found at Pos.=',MyPos,' in cleaned up String=',Source1);  MyChar:=GetPosString(Source2,'.(;',MyPos);  Writeln('Char=',MyChar,' found at Pos.=',MyPos,' in cleaned up String=',Source2);end. 
But there is something fishy with your Delimiters.
You're looking for opening Paranthesis, but not for closing?
Since when is a '-' a legal character in a Function-Header?
Since when can you use ':=' in a Function-Header?

CloseUp virtual;
This is wrong. There is a semicolon missing before virtual

If you really want parse out just the Function-Name, then '.', '(' and ';' is enough for Delimiters.
'.' if it's a Function of a class
'(' for the Parameters-List
';' if it's a function without parameters

If you want to parse out just the Name incl. Parameters-List, then use Delimiters '.():;'
'.' if it's a Function of a class
'(' for start of the Parameters-List
')' for end of Parameters-List
':' if it's a function
';' end of Function-header

Of course everytime you have to move your starting-position of "ASource" forward

Next: There is no reason to use an Array (or that thing with the Pipe-Symbols) at all. See my Function GetPosString

Navigation

[0] Message Index

[#] Next page

[*] Previous page

Go to full version