Delphi에 *SysUtils.Format*의 반대 기능이 있습니까?
문제
Delphi용 'UnFormat' 루틴을 작성한 사람이 있나요?
내가 상상하는 것은 역 ~의 SysUtils.Format 그리고 이런 것 같아
UnFormat('숫자 %n과 또 다른 %n',[float1, float2]);
따라서 형식 문자열을 사용하여 문자열을 일련의 변수로 압축해제할 수 있습니다.
SysUtils의 'Format' 루틴을 살펴봤지만 어셈블리를 사용해 본 적이 없기 때문에 의미가 없습니다.
해결책
이것은 C에서 scanf라고 하며, 저는 다음과 같이 Delphi와 비슷하게 만들었습니다.
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;
다른 팁
사람들이 겁을 먹는 경향이 있다는 건 알지만 정규식을 사용하여 이를 수행하는 간단한 함수를 작성할 수 있습니다.
'a number (.*?) and another (.*?)
reg 표현식이 걱정된다면 다음을 살펴보세요. www.regexbuddy.com 그리고 당신은 결코 뒤돌아보지 않을 것입니다.
나는 간단한 파서를 사용하여 이 문제를 처리하는 경향이 있습니다.두 가지 함수가 있습니다. 하나는 특정 구분 기호가 있는 문자열의 "부분" 수를 반환하는 NumStringParts(공백 위의 경우)이고 GetStrPart는 특정 구분 기호가 있는 문자열에서 특정 부분을 반환합니다.이 두 루틴은 터보 파스칼 시절부터 많은 프로젝트에서 사용되었습니다.
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;
사용 예:
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;
이러한 루틴은 단순하거나 엄격한 쉼표로 구분된 문자열에도 놀라운 효과를 발휘합니다.이러한 루틴은 Delphi 2009/2010에서 훌륭하게 작동합니다.
제휴하지 않습니다 StackOverflow