![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Поиск в строке 3ей запятой... [D6, Win95/98]
Michael C © (2002-02-12 10:27:00)Как осуществить, кто нить знает??? Я делал с помощью POS, но не получилось. А и ещё трабл, найти четвертую запятую и все что между ними COPY.
Народ выручайте... :(((
vuk (2002-02-12 15:09:00) [1]Ну и я тоже влезу. :o) Вот три функции - поиск слова с указания начальной позиции, выделения слова и подсчета количества слов.
function WordScan( const S : string; var StartPos, WordLen : integer; Delimiters : TSysCharSet ) : boolean;
var
i, l : integer;
begin
Result := false;
WordLen := 0;
i := StartPos;
l := length( s );
StartPos := 0;
while i <= l do
if s[i] in Delimiters then
inc(i)
else
begin
StartPos := i;
break;
end;
while i <= l do
if not(s[i] in Delimiters) then
begin
inc(i);
inc( WordLen );
end else
break;
Result := WordLen <> 0;
end;
function ExtractWord( const s : string; WordNumber : integer;
Delimiters : TSysCharSet ) : string;
var
wStart, wLen, n : integer;
begin
wStart := 1;
n := 0;
while WordScan( s, wStart, wLen, Delimiters ) do
begin
inc( n );
if n = WordNumber then
begin
Result := Copy( s, wStart, wLen );
exit;
end
else
inc( wStart, wLen );
end;
end;
function CountWords( const s : string; Delimiters : TSysCharSet ) : integer;
var
wStart, wLen : integer;
begin
Result := 0;
wStart := 1;
while WordScan( s, wStart, wLen, Delimiters ) do
begin
inc( Result );
inc( wStart, wLen );
end;
end;
McSimm (2002-02-12 15:00:00) [2]Не должна содержать пробелов, символов кавычек.
Для каких-то задач подойдет, но в общем случае - лучше через Text
oomneeq (2002-02-12 13:57:00) [3]2McSimm ©
Вместо
SL.Text := StringReplace(S, ",", #13#10,[rfReplaceAll]);
ecли заведомо нет пробелов
Проще писать
SL.CommaText := S;
Хотя не тестил, что из этого быстрее
Johnmen (2002-02-12 13:48:00) [4]кем (чем) ? :)
Romkin (2002-02-12 12:53:00) [5]а ты их считай, в цикле
Michael C (2002-02-12 12:31:00) [6]Народ, оказывается есть проблема!!!!
Строк в файле 15000!, как убедиться что они все до единой обрабатываются???
Michael C (2002-02-12 11:44:00) [7]Не сама строка, это 90 символов, но факт что строк таких эдак 500.
Romkin (2002-02-12 11:32:00) [8]Ну до кучи, если строка длинная (метров 15 хотя бы)
function TailPos(const S, SubStr: AnsiString; fromPos: integer): integer;
asm
PUSH EDI
PUSH ESI
PUSH EBX
PUSH EAX
OR EAX,EAX
JE @@2
OR EDX,EDX
JE @@2
DEC ECX
JS @@2
MOV EBX,[EAX-4]
SUB EBX,ECX
JLE @@2
SUB EBX,[EDX-4]
JL @@2
INC EBX
ADD EAX,ECX
MOV ECX,EBX
MOV EBX,[EDX-4]
DEC EBX
MOV EDI,EAX
@@1: MOV ESI,EDX
LODSB
REPNE SCASB
JNE @@2
MOV EAX,ECX
PUSH EDI
MOV ECX,EBX
REPE CMPSB
POP EDI
MOV ECX,EAX
JNE @@1
LEA EAX,[EDI-1]
POP EDX
SUB EAX,EDX
INC EAX
JMP @@3
@@2: POP EAX
XOR EAX,EAX
@@3: POP EBX
POP ESI
POP EDI
end;
function CommaN(const s: string; n: integer): integer;
var
i, APos: integer;
begin
APos := 0;
for i := 1 to n do
begin
APos := TailPos(s, ",", APos + 1);
if APos = 0 then break;
end;
Result := APos;
end;
При этом нарезки строки не производится, и выделения лишней памяти нет..
McSimm (2002-02-12 11:26:00) [9]типа как у Romkin © мой 1йвариант,
2йвариант пригодится, если надо получить весь список строк.
Никакой особой нагрузки на программу тут нет.
Вот хороший пример. Есть строка вида
"Key=123,ClassNo=5,Color=Red";
Чтобы получить значения по их имени, можно конечно написать парсинговую функцию, а можно так:
SL := TStringList.Create;
try
SL.Text := StringReplace(S, ",", #13#10,[rfReplaceAll]);
KeyStr := SL.Values["Key"];
ClassStr := SL.Values["ClassNo"];
ColorStr := SL.Values["Color"];
finally
SL.Free
end
IMHO, просто и изящно
Michael C (2002-02-12 11:20:00) [10]пасибо Народ, буду пробовать эти варианты,
Очень выручили....
Пасибо за асёмблер тоже, но ...
Johnmen (2002-02-12 11:13:00) [11]>McSimm © : Не стоит так грузить свою прогу из-за такой простой задачи !
Хороший вариант - это типа как у Romkin © !
Dimka Maslov (2002-02-12 11:09:00) [12]Str - строка
Ch - искомый символ
Entry - номер символа
для поиска третьей запятой - CharEntryPos(Str, ",", 3)
function CharEntryPos(const Str: string; Ch: Char; Entry: Integer): Integer; register;
asm
push edi
push esi
test eax, eax
jnz @@10
xor eax, eax
jmp @@50
@@10:
cmp ecx, 0
jnz @@20
xor eax, eax
jmp @@50
@@20:
mov edi, eax
dec edi
xor esi, esi
@@30:
inc edi
mov dh, [edi]
test dh, dh
jnz @@40
xor eax, eax
jmp @@50
@@40:
cmp dh, dl
jne @@30
inc esi
cmp esi, ecx
jne @@30
sub edi, eax
mov eax, edi
inc eax
@@50:
pop esi
pop edi
end;
McSimm (2002-02-12 11:07:00) [13]слова
>Могу предложить еще 2 варианта.
относятся к
>Michael C (12.02.02 10:47)
:)
McSimm (2002-02-12 11:04:00) [14]Могу предложить еще 2 варианта.
1й- Все-таки Pos(). Написать такую функцию не сложно.
sTmp := S; // Временная строка
K := Pos(",", sTmp); // Первая запятая
while K > 0 do
begin
ListBox1.Items.Add(Copy(sTmp, 1, K-1)); // очередное слово
sTmp := Copy(sTmp, K+1, Length(sTmp)); // отрезать
K := Pos(",", sTmp); // очередная запятая
end;
ListBox1.Items.Add(sTmp); // последнее слово
2й- С помощью TStringList:
SL := TStringList.Create;
try
SL.Text := StringReplace(S, ",", #13#10,[rfReplaceAll]);
// Здесь в нашем SL все строки уже разделены
finally
SL.Free
end
Romkin (2002-02-12 10:59:00) [15]for i := 1 to 3 do
begin
Apos := pos(",",s);
if APos > 0 then
delete(s,1,Apos);
end;
APos := pos(",",s);
if APos > 0 then
Result := copy(s,1,APos-1);
panov (M) (2002-02-12 10:54:00) [16]functionSearchString(const FindStr, SourceString: String;Num: Integer):Integer;
var
FirstP: PChar;
functionMyPos(const FindStr, SourceString: PChar;Num: Integer): PChar;
begin
Result := AnsiStrPos(SourceString,FindStr);
if(Result=nil) thenExit;
Inc(Result);
if Num=1 then Exit;
if num>1 then Result := MyPos(FindStr,Result,num-1);
end;
begin
FirstP := PChar(SourceString);
Result := MyPos(PChar(FindStr),PChar(SourceString),Num) - FirstP;
ifResult<0 thenResult := 0;
end;
Michael C (2002-02-12 10:47:00) [17]А если нету такой библиотеки, как быть???
McSimm (2002-02-12 10:38:00) [18]Если используете библиотеку RX, то есть простое решение:
uses
rxStrUtils; (или StrUtils для D5 и ниже)
for I := 1 to WordCount(S, [","]) do
SL.Add(ExtractWord(I, S, [","]))
В [","] можно перечислить несколько символов