【发布时间】:2011-02-09 21:13:54
【问题描述】:
我正在尝试使用 2 个分隔符从文本文件中提取字符串。一开始一停止。
例子:
Hi my name is$John and I'm happy/today
我需要做的是调用一个函数,该函数将返回$ 和/ 之间的字符串。我到处找,但似乎找不到有用的东西,而且我是编程新手。
【问题讨论】:
我正在尝试使用 2 个分隔符从文本文件中提取字符串。一开始一停止。
例子:
Hi my name is$John and I'm happy/today
我需要做的是调用一个函数,该函数将返回$ 和/ 之间的字符串。我到处找,但似乎找不到有用的东西,而且我是编程新手。
【问题讨论】:
全部搞定
function ExtractText(const Str: string; const Delim1, Delim2: string): TStringList;
var
c,pos1, pos2: integer;
begin
result:=TStringList.Create;
c:=1;
pos1:=1;
while pos1>0 do
begin
pos1 := PosEx(Delim1, Str,c);
if pos1 > 0 then begin
pos2 := PosEx(Delim2, Str, pos1+1);
if pos2 > 0 then
result.Add(Copy(Str, pos1 + length(delim1), pos2 - (length(delim1) + pos1)));
c:=pos1+1;
end;
end;
end;
【讨论】:
如果第二个文本也出现在第一个模式之前,则上述功能将不起作用...
您应该使用PosEx() 而不是Pos():
您可以使用 Pos 和 Copy 来做到这一点:
function ExtractText(const Str: string; const Delim1, Delim2: string): string;
var
pos1, pos2: integer;
begin
result := '';
pos1 := Pos(Delim1, Str);
if pos1 > 0 then begin
pos2 := PosEx(Delim2, Str, pos1+1);
if pos2 > 0 then
result := Copy(Str, pos1 + 1, pos2 - pos1 - 1);
end;
end;
【讨论】:
在较新的 Delphi 中,您可以这样做......(耶)
program Project40; {$APPTYPE CONSOLE}
uses RegularExpressions;
const
str = 'Is$John and I''m happy/today';
function GetStr(const aStr: string): string;
begin
Result := TRegEx.Match(aStr, '\$.*/').Value;
Result := Copy(Result, 2, Length(Result) - 2);
end;
begin
Writeln(GetStr(str));
ReadLn;
end.
【讨论】:
您可以使用Pos 和Copy 来做到这一点:
function ExtractText(const Str: string; const Delim1, Delim2: char): string;
var
pos1, pos2: integer;
begin
result := '';
pos1 := Pos(Delim1, Str);
pos2 := Pos(Delim2, Str);
if (pos1 > 0) and (pos2 > pos1) then
result := Copy(Str, pos1 + 1, pos2 - pos1 - 1);
end;
【讨论】:
PosEx在Delim1的位置之后开始搜索Delim2。
我会这样做:
function ExtractDelimitedString(const s: string): string;
var
p1, p2: Integer;
begin
p1 := Pos('$', s);
p2 := Pos('/', s);
if (p1<>0) and (p2<>0) and (p2>p1) then begin
Result := Copy(s, p1+1, p2-p1-1);
end else begin
Result := '';//delimiters not found, or in the wrong order; raise error perhaps
end;
end;
【讨论】:
Gab,您可以使用TFileStream 类以及Copy 和Pos 函数编写一个函数来执行此操作。
查看此示例:
uses
Classes,
SysUtils;
function ExtractString(Const FileName: TFileName;Const IDel,FDel : AnsiString) : AnsiString;
Var
FileStream : TFileStream;
i,f : Integer;
begin
FileStream:= TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); //oopen the file
try
try
SetLength(Result, FileStream.Size); //set the size of the string
FileStream.Read(Pointer(Result)^, FileStream.Size);//read the content into a string
i:=Pos(IDel,Result);//search the initial delimiter
f:=Pos(FDel,Result);//search the final delimiter
Result:=Copy(Result,i+1,f-i-1); //extract the value between the delimiters
except
Result := '';
raise;
end;
finally
FileStream.Free;
end;
end;
并以这种方式使用
ExtractString('your_file_name','$','/');
【讨论】:
根据您的帖子,假设两个分隔符都是单个字符:
function ExtractDelimitedValueFromFile(const aFilename: String;
const aOpenDelim: Char;
const aCloseDelim: Char;
var aValue: String): Boolean;
var
i: Integer;
strm: TStringStream;
delimStart: Integer;
delimEnd: Integer;
begin
result := FALSE;
aValue := '';
delimStart := -1;
delimEnd := -1;
strm := TStringStream.Create;
try
strm.LoadFromFile(aFileName);
for i := 1 to strm.Size do
begin
if (delimStart = -1) and (strm.DataString[i] = aOpenDelim) then
delimStart := i
else if (delimStart <> -1) and (strm.DataString[i] = aCloseDelim) then
delimEnd := i;
result := (delimStart <> -1) and (delimEnd <> -1);
if result then
begin
aValue := Copy(strm.DataString, delimStart + 1, delimEnd - delimStart - 1);
BREAK;
end;
end;
finally
strm.Free;
end;
end;
用法:
var
str: String;
begin
if ExtractDelimitedValueFromFile('path\filename.ext', '$', '/', str) then
// work with str
else
// delimited value not found in file
end;
【讨论】: