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

Windows 在delphi中从文本段落中提取第一行,windows,delphi,text,parsing,Windows,Delphi,Text,Parsing,我将文本传递给函数。该文本可以包含任何内容,从单个字符到整本书 我需要提取第一个like并将其用作“标题”,这样我就可以命名一个文件,并将该文本保存为备份。我正在使用以下工具: function GetTitle(var Text:string):string; var title: string; position: integer; begin title := ''; position := AnsiPos(#10, Text); if position

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

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

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,我似乎找不到一种处理方法

代码是赞赏的。谢谢你

嗯,这个很有效:

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;
该函数的更新版本

hmmm,此函数适用于:

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;

更新版本的函数

这可能不是最好的方法,但它确实消除了嵌套的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; 

这可能不是最好的方法,但它确实消除了嵌套的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; 

考虑到你输入的任意性,你所做的听起来是你能做的最多的事情,但这还不够,因为无法保证你任意文本中的第一句话足够短,可以成为标题。如果文本长度超过任意长度限制,则需要添加一个步骤来截断文本,并添加省略号(三个点…)以表示有更多的文本。

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

我将使用循环来解决此问题,可能比多次调用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; 
函数GetTitle(const Text:string):string;
变量
I:整数;
开始
I:=0;
而我是做这件事的
开始
如果(文本[I+1]在[#10,#13,'..]中),则
打破
公司(一);
终止
结果:=副本(文本,1,I);
终止

我会用一个循环来解决这个问题,可能比多次调用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; 
函数GetTitle(const Text:string):string;
变量
I:整数;
开始
I:=0;
而我是做这件事的
开始
如果(文本[I+1]在[#10,#13,'..]中),则
打破
公司(一);
终止
结果:=副本(文本,1,I);
终止
为什么不从字符串开头提取最多(比如)10个单词,同时忽略非法文件字符,如CR、LF、:。等等,如果它们存在的话

这就是标题吗

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

只是想一想:)

为什么不从字符串开头提取最多(比如)10个单词,同时忽略非法文件字符,如CR、LF、:。等等,如果它们存在的话

这就是标题吗

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


只是一个想法:)

首先,您应该使用
const Text:string
,而不是
var Text:string
。其次,您不需要
title
变量。只需一直使用
result
。首先,您应该使用
const Text:string
,而不是
var Text:string
。其次,您不需要
title
变量。只需一直使用
result
。首先,您应该使用
Text:string
,而不是
var Text:string
。您实际上正在销毁
文本
!其次,您不需要
title
变量。只需一直使用
result
。首先,您应该使用
Text:string
,而不是
var Text:string
。您实际上正在销毁
文本
!其次,您不需要
title
变量。只需一直使用
result
。+1。我会“为所有的#10、#13和..”获取ANSIPO,然后使用这三者中最小的一个。寻找空格可能不是个好主意。我也在检查空格,因为在没有任何指示符的情况下,我会将文本提取到第一个空格。它工作得很好,我只想在结尾添加一个空字符串检查,比如
如果结果='',那么结果:='Untitled'。没有这样的事情。我的意思是,在达到这个代码之前它是不被允许的,但是谢谢你指出+1。我会“为所有的#10、#13和..”获取ANSIPO,然后使用这三者中最小的一个。寻找空格可能不是个好主意。我也在检查空格,因为在没有任何指示符的情况下,我会将文本提取到第一个空格。它工作得很好,我只想在结尾添加一个空字符串检查,比如
如果结果='',那么结果:='Untitled'。没有这样的事情。我的意思是,在达到这个代码之前它是不被允许的,但是谢谢你指出这一点