从delphi中的文本段落中提取第一行

时间:2010-07-15 17:43:30

标签: windows delphi text parsing

我将文本传递给函数。该文本可以包含任何内容,从单个字符到完整的书。

我需要提取第一个并将其用作“标题”,这样我就可以命名一个文件,我将该文本保存为备份。我使用以下内容:

function GetTitle(var Text:string):string;
var
  title: string;
  position: integer;
begin
    title := '';
    position := AnsiPos(#10, Text);

    if position = 0 then
    begin
      position := AnsiPos('.', Text);
      if (position = 0) then
         title := Text
      else
         title := copy(Text, 1, position);
    end
    else
    begin
        title := copy(Text, 1, position);
    end;

    result := title;
end;

我正在检查#10而不是#13,因为文本可以从Windows应用程序或Mac OS X应用程序传递。如果没有#10我正在检查第一个。 (点)如果没有,那么我将整个事物作为标题传递 这种方法会导致名称中包含#13的文件名出现问题,或者名称太长。我可以为>添加支票标题是256,但这只是另一回事。

无论如何,有没有办法正确阅读第一行(包括#13#10或#10或#13或。或其他)?

我知道这很简单,但我似乎无法在没有嵌套ifs的情况下找到解决这个问题的方法......

代码表示赞赏。谢谢

5 个答案:

答案 0 :(得分:3)

嗯,这个有用:

function TForm1.SimpleNoteGetTitle(Text:string):string;
var
  position: integer;
begin
    position := AnsiPos(#13#10, Text);
    if (position = 0) or (position > 50) then position := AnsiPos(#10, Text);
    if (position = 0) or (position > 50) then position := AnsiPos(#13, Text);
    if (position = 0) or (position > 50) then position := AnsiPos('.', Text);
    if (position = 0) or (position > 50) then position := AnsiPos(',', Text);
    if (position = 0) or (position > 50) then position := AnsiPos(';', Text);
    if (position = 0) or (position > 50) then position := AnsiPos('?', Text);
    if (position = 0) or (position > 50) then position := AnsiPos('!', Text);
    if (position = 0) or (position > 50) then position := AnsiPos(' ', Text);

    if position = 0 then
       result := Text
    else
       result := copy(Text, 1, position - 1);
end;

功能的更新版本

答案 1 :(得分:3)

你所做的事情听起来就像你输入的任意性质一样,你可以做的最多但是它还不够,因为无法保证你的任意文本中的第一个句子足够短而不能成为一个标题。如果文本超过某个任意长度限制,则需要添加一个截断文本的步骤,并添加省略号(三个点......)以指示文本更多。

答案 2 :(得分:2)

这可能不是最好的方法,但它确实消除了嵌套的if ... ...

function GetTitle(var Text:string):string; 
var 
  position1: integer; 
  position2: integer; 
  position3: integer; 
  position: integer; 
begin 

    Text := copy(Text,0,255);

    position1 := AnsiPos(#10, Text); 
    position2 := AnsiPos(#13, Text); 
    position3 := AnsiPos('.', Text); 

    if position1 = 0 then position1 := 255;
    if position2 = 0 then position2 := 255;
    if position3 = 0 then position3 := 255;

    position := Min(Min(position1,position2),position3);

    result := copy(Text, 1, position); 

end; 

答案 3 :(得分:2)

我用循环解决问题,可能比多次调用Pos快一点。

function GetTitle(const Text:string):string; 
var 
  I: integer;
begin 
  I := 0;
  while I < Length(Text) do
  begin
    if (Text[I+1] in [#10,#13,'.']) then
      Break;
    Inc(I);
  end;
  Result := Copy(Text,1,I);
end; 

答案 4 :(得分:0)

为什么不从字符串的开头提取(比方说)10个单词,而忽略非法文件字符,如CR,LF,:.等等,如果他们存在。

并将其标题化?

更复杂但肯定会产生合法的文件名

只是一个想法:)