我有一行描述如下:' | 0200 | 4 | SALGADOS ||| KG | 00 | 19051000 |||| 17 |'
我想将数据库中保存数据的管道分开。
我错误地使用了pos功能。但我得到了数据。
在if中,我将数据插入db。
ReadLn(txt, line);
if True then
if (Pos('|0200|', line)) = 1 then
begin
fArq.Add(line);
end;
if (pos('|0000|', line)) = 1 then
begin
fArq.Add(line);
end;
if (pos('|0005|', line)) = 1 then
begin
fArq.Add(line);
end;
if (pos('|C460|', line)) = 1 then
begin
fArq.Add(line);
flagCF := True;
end
else
begin
if flagCF = True then
if (pos('|C490|', line)) = 0 then
fArq.Add(line)
else
flagCF := False;
end
答案 0 :(得分:7)
您也可以使用TStringList:
lStringList := TStringList.Create;
lStringList.delimiter := '|';
lStringList.DelimitedText := '|0200|4|SALGADOS|||KG|00|19051000||||17|';
现在您可以使用lStringList.Items [index]
访问每个字段 注意(来自评论):如果字符串中包含空格字符,请将StrictDelimiter
设置为true,以避免将它们视为分隔符。
答案 1 :(得分:2)
使用ExtractStrings
,您可以将| |的所有值添加到TStrings
- 后代。
假设fArq
是TStrings
后代:
ExtractStrings(['|'], [], PChar(line), fArq);
答案 2 :(得分:0)
如果您使用Delphi XE3及更高版本,则可以使用Split类助手方法。
parts:=line.Split(['|'],TStringSplitOptions.ExcludeEmpty);
答案 3 :(得分:0)
我有以下功能,我已经使用了很长时间。
这里有两种变体,第一种是一次性使用类型的函数,另一种是当你想要有效地处理从第一个元素到最后一个元素的整个输入字符串时。
我还包括相关函数来计算节数。
P.S。这些函数实际上是基于1写的。 P.P.S.我从另一个单元中撕下了这些功能,并没有检查这个单元是否完整正确。 YMMV。
非POS方法被认为是一次性功能。即。您只在给定的输入字符串中查找单个值。
POS方法采用两个加法整数变量来存储内部索引位置以供以后使用。第一次调用时,变量的初始值应设置为-1。之后,您应该只为前一次调用返回的调用的下一次迭代提供值。
例如。
非POS使用:
const
Str1 = '|0200|4|SALGADOS|||KG|00|19051000||||17|';
.
.
.
begin
showmessage( ParseSection(Str1, 1, '|') ); //returns 0200
showmessage( ParseSection(Str1, 4, '|') ); //returns '' (empty string)
//this will show every element in the string once
Idx1 := -1;
Idx2 := -1;
for loop := 1 to CountSections(Str1, '|') do
showmessage( ParseSectionPos(Str1, loop, '|', Idx1, Idx2) );
//Idx1 and Idx2 are self referenced variables and don't need outside intervention
//These are necessary to obtain the best possible speed
end;
方法的其他变体允许引用值和引用字符是用户定义的。
unit rmControls.Strings.Sections;
interface
uses System.Classes, System.SysUtils;
function CountSections(const ParseLine: string; const ParseSep: char): integer; overload;
function CountSections(const ParseLine: string; const ParseSep: char; const QuotedStrChar: char): integer; overload;
function ParseSection(const ParseLine: string; ParseNum: integer; const ParseSep: char): string; overload;
function ParseSection(const ParseLine: string; ParseNum: integer; const ParseSep: char; const QuotedStrChar: char): string; overload;
function ParseSectionPos(const ParseLine: string; ParseNum: integer; const ParseSep: char; var FromIDX, FromPOS: integer): string; overload;
function ParseSectionPos(const ParseLine: string; ParseNum: integer; const ParseSep: char; const QuotedStrChar: char; var FromIDX, FromPOS: integer): string; overload;
function UpdateSection(const ParseLine, UpdateText: string; ParseNum: integer; const ParseSep: char):string; overload;
function UpdateSection(const ParseLine, UpdateText: string; ParseNum: integer; const ParseSep: char; const QuotedStrChar: char):string; overload;
function UpdateSectionPos(const ParseLine, UpdateText: string; ParseNum: integer; const ParseSep: char; var FromIDX, FromPOS: integer):string; overload;
function UpdateSectionPos(const ParseLine, UpdateText: string; ParseNum: integer; const ParseSep: char; const QuotedStrChar: char; var FromIDX, FromPOS: integer):string; overload;
implementation
uses System.Math, System.Masks, System.Character, System.Variants;
function CountSections(const ParseLine: string; const ParseSep: char; const QuotedStrChar: char): integer; overload;
var
wEnd: PChar;
Loop: integer;
wInQuote: boolean;
begin
wInQuote := false;
wEnd := PChar(ParseLine);
result := 0;
for Loop := 1 to Length(ParseLine) do
begin
if (wEnd^ = QuotedStrChar) then
wInQuote := not wInQuote;
if not wInQuote and (wEnd^ = ParseSep) then
inc(result);
inc(wEnd);
end;
if Length(ParseLine) <> 0 then
inc(result);
end; { CountSections }
function CountSections(const ParseLine: string; const ParseSep: char): integer; overload;
var
wEnd: PChar;
Loop: integer;
begin
wEnd := PChar(ParseLine);
result := 0;
for Loop := 1 to Length(ParseLine) do
begin
if (wEnd^ = ParseSep) then
inc(result);
inc(wEnd);
end;
if Length(ParseLine) <> 0 then
inc(result);
end; { CountSections }
function ParseSection(const ParseLine: string; ParseNum: integer; const ParseSep: char): string; overload;
var
w1, w2: integer;
begin
w1 := -1;
w2 := -1;
result := ParseSectionPos(ParseLine, ParseNum, ParseSep, w1, w2);
end; { ParseSection }
function ParseSection(const ParseLine: string; ParseNum: integer; const ParseSep: char; const QuotedStrChar: char): string; overload;
var
w1, w2: integer;
begin
w1 := -1;
w2 := -1;
result := ParseSectionPos(ParseLine, ParseNum, ParseSep, QuotedStrChar, w1, w2);
end; { ParseSection }
function ParseSectionPos(const ParseLine: string; ParseNum: integer; const ParseSep: char; var FromIDX, FromPOS: integer): string;
var
wStart, wEnd: PChar;
wIndex, Loop: integer;
wLoopIDX: integer;
begin
wIndex := 1;
wLoopIDX := 1;
wEnd := PChar(ParseLine);
if (FromIDX > -1) and (FromIDX < Length(ParseLine)) then
begin
inc(wEnd, FromIDX);
wIndex := FromPOS;
wLoopIDX := FromIDX;
end;
wStart := wEnd;
for Loop := wLoopIDX to Length(ParseLine) do
begin
if (wEnd^ = ParseSep) then
begin
if wIndex = ParseNum then
break
else
begin
inc(wIndex);
inc(wEnd);
wStart := wEnd;
end;
end
else
inc(wEnd);
end;
if wIndex = ParseNum then
begin
SetString(result, wStart, wEnd - wStart);
if result = #0 then
result := '';
FromIDX := wEnd - PChar(ParseLine);
FromPOS := ParseNum;
end
else
result := '';
end;
function ParseSectionPos(const ParseLine: string; ParseNum: integer; const ParseSep: char; const QuotedStrChar: char; var FromIDX, FromPOS: integer): string;
var
wStart, wEnd: PChar;
wIndex, Loop: integer;
wInQuote: boolean;
wLoopIDX: integer;
begin
wInQuote := false;
wIndex := 1;
wLoopIDX := 1;
wEnd := PChar(ParseLine);
if (FromIDX > -1) and (FromIDX < Length(ParseLine)) then
begin
inc(wEnd, FromIDX);
wIndex := FromPOS;
wLoopIDX := FromIDX;
end;
wStart := wEnd;
for Loop := wLoopIDX to Length(ParseLine) do
begin
if (wEnd^ = QuotedStrChar) then
wInQuote := not wInQuote;
if not wInQuote and (wEnd^ = ParseSep) then
begin
if wIndex = ParseNum then
break
else
begin
inc(wIndex);
inc(wEnd);
wStart := wEnd;
end;
end
else
inc(wEnd);
end;
if wIndex = ParseNum then
begin
SetString(result, wStart, wEnd - wStart);
if (Length(result) > 0) and (result[1] = QuotedStrChar) then
result := AnsiDequotedStr(result, QuotedStrChar);
if result = #0 then
result := '';
FromIDX := wEnd - PChar(ParseLine);
FromPOS := ParseNum;
end
else
result := '';
end;
function UpdateSection(const ParseLine, UpdateText: string; ParseNum: integer; const ParseSep: char): string; overload;
var
w1, w2: integer;
begin
w1 := -1;
w2 := -1;
result := UpdateSectionPos(ParseLine, UpdateText, ParseNum, ParseSep, w1, w2);
end;
function UpdateSection(const ParseLine, UpdateText: string; ParseNum: integer; const ParseSep: char; const QuotedStrChar: char): string; overload;
var
w1, w2: integer;
begin
w1 := -1;
w2 := -1;
result := UpdateSectionPos(ParseLine, UpdateText, ParseNum, ParseSep, QuotedStrChar, w1, w2);
end;
function UpdateSectionPos(const ParseLine, UpdateText: string; ParseNum: integer; const ParseSep: char; var FromIDX, FromPOS: integer):string; overload;
var
wStart, wEnd: PChar;
wIndex, Loop: integer;
wLoopIDX: integer;
begin
wIndex := 1;
wLoopIDX := 1;
wEnd := PChar(ParseLine);
if (FromIDX > -1) and (FromIDX < Length(ParseLine)) then
begin
inc(wEnd, FromIDX);
wIndex := FromPOS;
wLoopIDX := FromIDX;
end;
wStart := wEnd;
for Loop := wLoopIDX to Length(ParseLine) do
begin
if (wEnd^ = ParseSep) then
begin
if wIndex = ParseNum then
break
else
begin
inc(wIndex);
inc(wEnd);
wStart := wEnd;
end;
end
else
inc(wEnd);
end;
if wIndex = ParseNum then
begin
SetString(result, PChar(ParseLine), wStart - pChar(ParseLine));
if result = #0 then
result := '';
result := result + updateText + pchar(wEnd);
FromIDX := wEnd - PChar(ParseLine);
FromPOS := ParseNum;
end
else
raise Exception.Create('Index not found');
end;
function UpdateSectionPos(const ParseLine, UpdateText: string; ParseNum: integer; const ParseSep: char; const QuotedStrChar: char; var FromIDX, FromPOS: integer):string; overload;
var
wStart, wEnd: PChar;
wIndex, Loop: integer;
wInQuote: boolean;
wLoopIDX: integer;
begin
wInQuote := false;
wIndex := 1;
wLoopIDX := 1;
wEnd := PChar(ParseLine);
if (FromIDX > -1) and (FromIDX < Length(ParseLine)) then
begin
inc(wEnd, FromIDX);
wIndex := FromPOS;
wLoopIDX := FromIDX;
end;
wStart := wEnd;
for Loop := wLoopIDX to Length(ParseLine) do
begin
if (wEnd^ = QuotedStrChar) then
wInQuote := not wInQuote;
if not wInQuote and (wEnd^ = ParseSep) then
begin
if wIndex = ParseNum then
break
else
begin
inc(wIndex);
inc(wEnd);
wStart := wEnd;
end;
end
else
inc(wEnd);
end;
if wIndex = ParseNum then
begin
SetString(result, PChar(ParseLine), wStart - pChar(ParseLine));
if result = #0 then
result := '';
result := result + AnsiQuotedStr(updateText, QuotedStrChar) + pchar(wEnd);
FromIDX := wEnd - PChar(ParseLine);
FromPOS := ParseNum;
end
else
raise Exception.Create('Index not found');
end;
end.
答案 4 :(得分:0)
这是我使用的功能。它支持任意长度定界符(用于拆分CRLF分隔的字符串,f.i。)和AllowEmpty
参数,该参数确定是否省略或返回空元素。
function Split(const Str: string; Delim: string; AllowEmpty: Boolean): TStringDynArray;
var CurrDelim, NextDelim, CurrIdx: Integer;
begin
if Str = '' then begin SetLength(Result, 0); Exit; end;
CurrDelim := 1; CurrIdx := 0; SetLength(Result, 16);
repeat
if CurrIdx = Length(Result) then
SetLength(Result, CurrIdx + 16);
NextDelim := PosEx(Delim, Str, CurrDelim);
if NextDelim = 0 then NextDelim := Length(Str)+1; // the end of the string
Result[CurrIdx] := Copy(Str, CurrDelim, NextDelim - CurrDelim);
CurrDelim := NextDelim + Length(Delim);
if (Result[CurrIdx] <> '') or AllowEmpty
then Inc(CurrIdx)
else Continue;
until CurrDelim > Length(Str);
SetLength(Result, CurrIdx); // cut the array to actual length
end;