Windows 在delphi中从文本段落中提取第一行
我将文本传递给函数。该文本可以包含任何内容,从单个字符到整本书 我需要提取第一个like并将其用作“标题”,这样我就可以命名一个文件,并将该文本保存为备份。我正在使用以下工具: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
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'代码>。没有这样的事情。我的意思是,在达到这个代码之前它是不被允许的,但是谢谢你指出这一点