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

发布于 2024-10-20 06:41:59 字数 521 浏览 2 评论 0原文

我有一个使用字符串(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;

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

I have a program which works with strings (Pascal). After reading a string if the first char is not a letter then I need to delete all first characters until the first is a letter. I have tried to write it several times, but always it deletes all string or nothing.

If program reads "123%^&abc" then result should be "abc"
In ASCII table letters are from 65..90 and from 97..122

This is how far I am:

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;

I don't understand why it does not work?
Can you help me with this little procedure? Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

合约呢 2024-10-27 06:41:59

您可以执行

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;

or 作为一个过程

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,请参阅

那么,为什么你的算法不起作用?嗯,它应该有效,而且对我也有效。但请注意,它可以用稍微更优雅的形式编写

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 完全由非字母字符组成(例如 '!"#¤%),它也不起作用。

You could do

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;

or, as a procedure

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;

For more sophisticated methods, that also work with Unicode Delphi, see my answer to a similar question. [This removes all non-alpha chars from the string.]

So, why doesn't your algorithm work? Well, it should work, and it works for me. But notice that it can be written in the slightly more elegant form

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);

One problem, however, with the OP's original code is that it will fail if s is the empty string. Indeed, then s[1] doesn't exist. It won't work either if s consists entirely of non-alpha characters (e.g. '!"#¤%).

顾挽 2024-10-27 06:41:59

尽管以前的解决方案确实有效,但效率非常低。由于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;

Allthough the previous solutions do work, they are highly ineffitient. Because of 2 reasons:
1. Searching in a set is time consuming
2. Deleting every time a character out of a string is even more ineffitient, as the string (object) has to remove the character internally and adjust its array, etc.

Ideally you cast your string into PChar and work with that, while checking the char-range "manually". We'll let the search run until we find the first letter and only then we call the DeleteString method. Here's a demo on my approach:

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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文