DELPHI STRING:从全名中提取姓氏

| 我试图操纵一个字符串并从中仅提取某些数据。我需要在从数据库中提取的记录中执行此操作,该记录为我提供了一个人的全名。我只需要从字符串中提取姓氏并将其存储为变量。有办法可以做到吗? 示例:SQL查询提取完整字段\“ Mary Ellen Jones \”我只需要从字符串中提取Jones,以便可以将其存储在变量中以进行进一步处理。 我以为AnsiRightStr可能会起作用,但是问题是需要给它一个设置整数以从右侧拉出。也许是一种在最后一个空格之后计算字符的方法,允许我为此使用AnsiRightStr(string,int)?任何帮助都表示赞赏。 额外的想法:是否可以用定界符替换空格:::然后将数据解析为Stringlist,然后允许我提取字符串列表的最后一个索引? 到目前为止,已经提出了几种有效的选择。如果说“ John J. Jr.”之类的名字,他们都无法解决这个问题吗?     
已邀请:
           如果姓氏说“圣詹姆斯”怎么办? 这是我的方法。 列出姓氏标记 按偏好顺序搜索该列表 找到匹配项后,将其标记为姓氏的开头 从该pos返回子字符串。 变种   LastNameMarkers:TStringList = nil;   后缀修复: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;
我没有正确处理大写和小写字母,但希望您能理解。     
        您可以使用
LastDelimiter
函数获取最后的空格位置,然后使用
copy
函数提取子字符串。
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;
或使用功能
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;
    
        
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;
如果字符串以('偶然的)空格结尾,则失败,例如\'Andreas Rejbrand \'。这个更强大的版本也可以处理这种情况:
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;
    
        
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;
这两个功能共同实现了我需要做的事情。还有一个initlists函数笨拙而丑陋,我需要继续工作,所以我没有在这里发布它。     

要回复问题请先登录注册