2010-07-15 99 views
1

我將文本傳遞給一個函數。該文本可以包含任何內容,從單個字符到全書。從delphi中的文本段落中提取第一行

我需要提取第一個像並將其用作「標題」,以便我可以命名一個文件作爲備份保存該文本。我使用了以下內容:

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 ...

代碼表示讚賞。謝謝

+0

首先,你應該使用'const的文字:string',不'VAR文字:string'。其次,你不需要'title'變量。只需簡單地使用'result'。 – 2010-07-15 17:56:03

回答

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; 

功能更新版本

+0

+1。 Id'get AnsiPos的#10,#13和'。'然後使用其中最小的那三個。尋找空間可能不是一個好主意。 – 2010-07-16 05:44:11

+0

我正在檢查空間,因爲在沒有任何指標的情況下,我會將文本提取到第一空間。它的工作很好 – Uri 2010-07-16 13:10:42

+0

我只是在最後添加一個空字符串檢查,某事。像'if Result =''那麼結果:='無標題';'。 – 2010-07-16 13:43:19

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; 
+2

首先,你應該使用'Text:string',而不是'var Text:string'。你實際上是在摧毀'文字'!其次,你不需要'title'變量。只需簡單地使用'result'。 – 2010-07-15 17:56:39

+0

@andreas:謝謝你的提示 – Uri 2010-07-15 18:03:50

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; 
+0

讓我試試看。謝謝! – Uri 2010-07-16 13:12:05

0

爲什麼不從字符串的開頭提取(說)10個字,而忽略非法文件字符,如CR,LF,:。如果它們存在的話。

並使該標題?

更復雜,但是肯定會產生一個合法的文件名

只是一個想法:)