如何从字符串中删除字符,直到第一个字符是一个字母?

时间:2011-03-06 11:35:36

标签: string delphi pascal

我有一个使用字符串(Pascal)的程序。如果第一个字符不是字母,读取字符串后,我需要删除所有第一个字符,直到第一个字符为一个字母。我曾尝试多次写它,但总是删除所有字符串或没有。

如果程序显示“123%^& abc”,则结果应为“abc” 在ASCII表格中,字母是65..90和97..122

这就是我的目标:

variables    a: set of 65..90;
             b: set of 97..122;
-------------------
  bool:=false;
  While (bool=false) do
  begin
    Writeln(s[1]);
    If (Ord(s[1]) in a) or (Ord(s[1]) in b) then
    begin
    bool:=true;
    end else
    delete(s,1,1);
  end;

我不明白为什么它不起作用? 你能用这个小程序帮我吗?谢谢。

2 个答案:

答案 0 :(得分:13)

你可以做到

function RemoveNonAlphaASCIIFromStart(const Str: AnsiString): AnsiString;
const
  ALPHA = ['A'..'Z', 'a'..'z'];
var
  i: Integer;
  firstIndex: integer;
begin
  result := '';
  firstIndex := 0;
  for i := 1 to length(Str) do
    if Str[i] in ALPHA then
    begin
      firstIndex := i;
      break;
    end;
  if firstIndex > 0 then
    result := Copy(Str, firstIndex, length(Str));
end;

或作为程序

procedure RemoveNonAlphaASCIIFromStart(var Str: AnsiString);
const
  ALPHA = ['A'..'Z', 'a'..'z'];
var
  i: Integer;
  firstIndex: integer;
begin
  firstIndex := 0;
  for i := 1 to length(Str) do
    if Str[i] in ALPHA then
    begin
      firstIndex := i;
      break;
    end;
  if firstIndex > 0 then
    Delete(Str, 1, firstIndex - 1)
  else
    Str := '';
end;

对于更复杂的方法,也适用于Unicode Delphi,请参阅my answer to a similar question。 [这将从字符串中删除所有非alpha字符。]

那么,为什么你的算法不起作用?嗯,它应该工作,它适用于我。但请注意,它可以用稍微优雅的形式编写

const
  ALPHA = ['A'..'Z', 'a'..'z'];

while true do
  if (length(s) = 0) or (s[1] in ALPHA) then
    break
  else
    delete(s, 1, 1);

然而,OP的原始代码存在的一个问题是,如果s为空字符串,它将失败。实际上,s[1]不存在。如果s完全由非字母字符组成(例如'!"#¤%),则无效。

答案 1 :(得分:2)

尽管以前的解决方案确实有效,但它们非常不合适。由于两个原因: 1.搜索集合非常耗时 2.每次字符串中的字符删除时更加无效,因为字符串(对象)必须在内部删除字符并调整其数组等。

理想情况下,您将字符串转换为PChar并使用它,同时“手动”检查字符范围。我们将让搜索运行直到找到第一个字母,然后才调用DeleteString方法。这是我的方法演示:

procedure Frapp;
var
  TheString: string;
  pcStr: PChar;
  StrLen, I: Integer;
begin
  TheString := '123%^&abc';
  StrLen := Length(TheString);
  pcStr := PChar(TheString);

  for I := 0 to StrLen - 1 do
  begin
    if ((pcStr^ >= #65) and (pcStr <= #90)) or ((pcStr >= #97) and (pcStr <= #122)) then
    begin
      Delete(TheString, 1, I);
      Break;
    end;
    Inc(pcStr);
  end;
end;