开发者

extracting the first line out of a text paragraph in delphi

I have text being passed to a function. That text can contain anything, from a single chara开发者_如何学JAVActer all the way to a full book.

I need to extract the first like and use it as a "title" so I can name a file where I am saving that text as a backup. I am using the following:

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;

I'm checking #10 and not #13 because the text can be either passed from a Windows app or a Mac OS X app. In cases where there is no #10 I'm checking for the 1st . (dot) and if there is none then I am passing the whole thing as a title.

This approach is causing some problems with filenames containing #13 in the name or names being too long. I can add a check for > 256 on title but that's just another thing.

Anyway, is there any way to properly read the first line (including #13#10 or #10 or #13 or . or whatever)?

I know this is simple, but I can't seem to find a way to deal with this without having nested ifs...

code is appreciated. thank you


What you're doing sounds like the most you can do given the arbitrary nature of your input, but it's not going to be enough because there is no guarantee that the first sentence in your arbitrary text will be short enough to be a title. You need to add a step to truncate the text if it is longer than some arbitrary length limit, and add ellipsis (three dots ...) to indicate that there is more text.


hmmm, this one works:

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;

UPDATED version of the function


This may not be the best way, but it does eliminate the nested if's...

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; 


I'd tackle the problem with a loop, probably a bit faster than multiple calls to 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; 


Why not extract up to (say) 10 words from the beginning of the string while ignoring illegal file characters such as CR, LF, : . etc if they exist.

and make that the title?

more complex but certain to produce a legal filename

just a thought :)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜