Gibt es eine inverse Funktion *SysUtils.Format* in Delphi
Frage
Hat jemand geschrieben, ein "UnFormat" routine für Delphi?
Was ich mir vorstelle, ist die inverse von SysUtils.Format und sieht ungefähr so aus
UnFormat('eine Nummer %n und andere %n',[float1, float2]);
Man könnte also packen Sie eine Zeichenfolge in eine Reihe von Variablen, die Verwendung von format-strings.
Ich habe die 'Format' - routine in SysUtils, aber ich habe noch nie verwendet-Montage, so es ist bedeutungslos für mich.
Lösung
Dies nennt man scanf in C, ich habe eine Delphi-look-a-like für dieses :
function ScanFormat(const Input, Format: string; Args: array of Pointer): Integer;
var
InputOffset: Integer;
FormatOffset: Integer;
InputChar: Char;
FormatChar: Char;
function _GetInputChar: Char;
begin
if InputOffset <= Length(Input) then
begin
Result := Input[InputOffset];
Inc(InputOffset);
end
else
Result := #0;
end;
function _PeekFormatChar: Char;
begin
if FormatOffset <= Length(Format) then
Result := Format[FormatOffset]
else
Result := #0;
end;
function _GetFormatChar: Char;
begin
Result := _PeekFormatChar;
if Result <> #0 then
Inc(FormatOffset);
end;
function _ScanInputString(const Arg: Pointer = nil): string;
var
EndChar: Char;
begin
Result := '';
EndChar := _PeekFormatChar;
InputChar := _GetInputChar;
while (InputChar > ' ')
and (InputChar <> EndChar) do
begin
Result := Result + InputChar;
InputChar := _GetInputChar;
end;
if InputChar <> #0 then
Dec(InputOffset);
if Assigned(Arg) then
PString(Arg)^ := Result;
end;
function _ScanInputInteger(const Arg: Pointer): Boolean;
var
Value: string;
begin
Value := _ScanInputString;
Result := TryStrToInt(Value, {out} PInteger(Arg)^);
end;
procedure _Raise;
begin
raise EConvertError.CreateFmt('Unknown ScanFormat character : "%s"!', [FormatChar]);
end;
begin
Result := 0;
InputOffset := 1;
FormatOffset := 1;
FormatChar := _GetFormatChar;
while FormatChar <> #0 do
begin
if FormatChar <> '%' then
begin
InputChar := _GetInputChar;
if (InputChar = #0)
or (FormatChar <> InputChar) then
Exit;
end
else
begin
FormatChar := _GetFormatChar;
case FormatChar of
'%':
if _GetInputChar <> '%' then
Exit;
's':
begin
_ScanInputString(Args[Result]);
Inc(Result);
end;
'd', 'u':
begin
if not _ScanInputInteger(Args[Result]) then
Exit;
Inc(Result);
end;
else
_Raise;
end;
end;
FormatChar := _GetFormatChar;
end;
end;
Andere Tipps
Ich weiß, dass es dazu neigt, Leute zu erschrecken, aber Sie konnten schreiben Sie eine einfache Funktion, um dies mit regulären Ausdrücken
'a number (.*?) and another (.*?)
Wenn Sie besorgt über die reg Ausdrücke werfen Sie einen Blick auf www.regexbuddy.com und Sie werden nie Blick zurück.
Ich Neige dazu, darauf achten, dieses mit einem einfachen parser.Ich habe zwei Funktionen, eine ist genannt NumStringParts gibt die Anzahl der "Teile" in einem string mit einem bestimmten Trennzeichen (in Ihrem Fall über den Raum) und GetStrPart gibt den bestimmten Teil aus einem string mit einem bestimmten Trennzeichen.Diese beiden Routinen verwendet wurden, da mein Turbo Pascal Tagen in vielen ein Projekt.
function NumStringParts(SourceStr,Delimiter:String):Integer;
var
offset : integer;
curnum : integer;
begin
curnum := 1;
offset := 1;
while (offset <> 0) do
begin
Offset := Pos(Delimiter,SourceStr);
if Offset <> 0 then
begin
Inc(CurNum);
Delete(SourceStr,1,(Offset-1)+Length(Delimiter));
end;
end;
result := CurNum;
end;
function GetStringPart(SourceStr,Delimiter:String;Num:Integer):string;
var
offset : integer;
CurNum : integer;
CurPart : String;
begin
CurNum := 1;
Offset := 1;
While (CurNum <= Num) and (Offset <> 0) do
begin
Offset := Pos(Delimiter,SourceStr);
if Offset <> 0 then
begin
CurPart := Copy(SourceStr,1,Offset-1);
Delete(SourceStr,1,(Offset-1)+Length(Delimiter));
Inc(CurNum)
end
else
CurPart := SourceStr;
end;
if CurNum >= Num then
Result := CurPart
else
Result := '';
end;
Beispiel der Nutzung:
var
st : string;
f1,f2 : double;
begin
st := 'a number 12.35 and another 13.415';
ShowMessage('Total String parts = '+IntToStr(NumStringParts(st,#32)));
f1 := StrToFloatDef(GetStringPart(st,#32,3),0.0);
f2 := StrToFloatDef(GetStringPart(st,#32,6),0.0);
ShowMessage('Float 1 = '+FloatToStr(F1)+' and Float 2 = '+FloatToStr(F2));
end;
Diese Routinen, die Arbeit Wunder für die einfachen oder strengen Komma getrennten Zeichenfolgen zu.Diese Routinen funktionieren wunderbar in Delphi 2009/2010.