DELPHI STRING: pull last name from full name

I am trying to manipulate a string and extract only certain data from it. I need to do this on a record retrieved from a database that gives me the full name of the person. I need to infer only the name from the string and save it as a variable. Is there a way I can do this?

Example: SQL query pulls the full field "Mary Ellen Jones" I need to extract only Jones from the string so that I can save it in a variable for further processing.

I thought maybe AnsiRightStr would work, but the problem is to give it an integer to pull to the right. Maybe a way of counting characters after the last space, allowing me to use AnsiRightStr (string, int) for this? Any help is generally appreciated.

Additional thought: would replace the spaces with say :: separator and then parse this data into a Stringlist, after which it would be possible to pull out the last index of the list of strings?

So far, several valid parameters have been presented. None of them turn to the situation if they say that this name is “Something like” John St. James Jr. “Is this impossible?

+7
source share
4 answers

What if the last name says “St. James” to somehow explain this?

Here is my approach.

  • List lastname markers
  • Search this list in order of preference
  • Once a match is found, mark this as the beginning of the last name
  • Returned substring starting at this position.
  var
   LastNameMarkers: TStringList = nil;
   SuffixFix: TStringList = nil;
procedure InitLists; begin LastNameMarkers:= TStringList.Create; //LastNameMarkers.LoadFromFile('c:\markers.txt'); LastNameMarkers.Add(' St.'); LastnameMarkers.Add(' Mc'); LastNameMarkers.Add(' '); //Marker of last resort. SuffixFix:= TStringList.Create; SuffixFix.Add(' Jr.'); SuffixFix.Add(' Sr.'); end; function GetLastName(FullName: string): string; var i: integer; start: integer; found: boolean; ReplaceWith: string; begin if LastNameMarkers = nil then InitLists; //Fix suffixes i:= 0; found:= false; while (i < SuffixFix.Count) and not found do begin start:= pos(lower(LastNameMarkers[i]),lower(Fullname)); found:= Start > 0; Inc(i); end; {while} if Found then begin Dec(i); ReplaceWith:= StringReplace(Suffix[i], ' ', '_',[]); FullName:= StringReplace(FullName, SuffixFix[i], ReplaceWith,[]); end; {if} //Look for lastnames i:= 0; found:= false; while (i < LastNameMarkers.Count) and not found do begin start:= pos(LastNameMarkers[i],Fullname); found:= Start > 0; Inc(i); end; {while} if found then Result:= RightStr(FullName, Length(FullName)- Start + 2) else Result:= ''; StringReplace(Result, '_', ' ',[]); end; 

I did not consider upper and lower case correctly, but I hope you understand this idea.

+5
source

you can use the LastDelimiter function to get the last space position, and then using copy function retrieves the substring.

 uses SysUtils; var Name : string; p : Integer; ShortName : string; begin Name:='Mary Ellen Jones'; //You can call trim to avoid problems with ending spaces in this case is not necesary, just is a test //Name:=Trim(Name); //get the last space position p:=LastDelimiter(' ',Name); //get the name ShortName:=Copy(Name,p+1,length(Name)-p); end; 

or using the function

 function GetLast(const Name:string) : string; var p : Integer; begin Result:=Trim(Name); p:=LastDelimiter(' ',Result); Result:=Copy(Result,p+1,length(Result)-p); end; 
+7
source
 function GetLastWord(const Str: string): string; var p: integer; i: Integer; const SPACE = #$20; begin p := 1; for i := length(Str) downto 1 do if Str[i] = SPACE then begin p := i + 1; break; end; result := Copy(Str, p, MaxInt); end; 

This will fail if the line ends in (random) space, like "Andreas Rejbrand". This more robust version will also handle this case:

 function GetLastWord(const Str: string): string; var p: integer; i: Integer; FoundNonSpace: boolean; const SPACE = #$20; begin p := 1; FoundNonSpace := false; for i := length(Str) downto 1 do if (Str[i] = SPACE) and FoundNonSpace then begin p := i + 1; break end else if Str[i] <> SPACE then FoundNonSpace := true; result := TrimRight(Copy(Str, p, MaxInt)); end; 
+6
source
 function TfrmCal.GetLastName(FullName: string): string; var i: integer; found: boolean; suffix: string; marker: string; begin // Build the lists for the compare. InitLists; // Look at Suffixes and attach them to the LastName i := 0; found := False; while (i < SuffixFix.Count) do begin if AnsiContainsStr(FullName, SuffixFix[i]) then begin suffix := '::' + trim(SuffixFix[i]); FullName := ReplaceStr(FullName, SuffixFix[i], suffix); found := True; end; inc(i); if found then break; end; // Look for LastName Markers i := 0; found := False; while (i < LastNameMarkers.Count) do begin if AnsiContainsStr(FullName, LastNameMarkers[i]) then begin marker := trimright(LastNameMarkers[i]) + '::'; FullName := ReplaceStr(FullName, LastNameMarkers[i], marker); found := True; end; inc(i); if found then break; end; FullName := GetLastWord(FullName); FullName := ReplaceStr(FullName, '::', ' '); LastNameMarkers.Clear; SuffixFix.Clear; Result := FullName; end; function TfrmCal.GetLastWord(const Str: string): string; var p: integer; i: integer; const SPACE = #$20; begin p := 1; for i := Length(Str) downto 1 do if Str[i] = SPACE then begin p := i + 1; break; end; Result := Copy(Str, p, MaxInt); end; 

These two functions together remove what I need to do. There is also an initlists function, which is clumsy and ugly, and I need to work, so I did not publish it here.

0
source

All Articles