Форум: "Основная";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.02.28;
Скачать: [xml.tar.bz2];




Вниз

Поиск в строке 3ей запятой... 


Michael C   (2002-02-12 10:27) [0]

Как осуществить, кто нить знает??? Я делал с помощью POS, но не получилось. А и ещё трабл, найти четвертую запятую и все что между ними COPY.
Народ выручайте... :(((



McSimm   (2002-02-12 10:38) [1]

Если используете библиотеку RX, то есть простое решение:

uses
rxStrUtils; (или StrUtils для D5 и ниже)

for I := 1 to WordCount(S, [","]) do
SL.Add(ExtractWord(I, S, [","]))

В [","] можно перечислить несколько символов



Michael C   (2002-02-12 10:47) [2]

А если нету такой библиотеки, как быть???



panov (M)   (2002-02-12 10:54) [3]

function SearchString(const FindStr, SourceString: String;Num: Integer):Integer;
var
FirstP: PChar;
function MyPos(const FindStr, SourceString: PChar;Num: Integer): PChar;
begin
Result := AnsiStrPos(SourceString,FindStr);
if (Result=nil) then Exit;
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;
if Result<0 then Result := 0;
end;



Romkin   (2002-02-12 10:59) [4]

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);



McSimm   (2002-02-12 11:04) [5]

Могу предложить еще 2 варианта.
- Все-таки 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); // последнее слово


- С помощью TStringList:
SL := TStringList.Create;
try
SL.Text := StringReplace(S, ",", #13#10,[rfReplaceAll]);
// Здесь в нашем SL все строки уже разделены
finally
SL.Free
end



McSimm   (2002-02-12 11:07) [6]

слова
>Могу предложить еще 2 варианта.
относятся к
>Michael C (12.02.02 10:47)

:)



Dimka Maslov   (2002-02-12 11:09) [7]

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;



Johnmen   (2002-02-12 11:13) [8]

>McSimm © : Не стоит так грузить свою прогу из-за такой простой задачи !
Хороший вариант - это типа как у Romkin © !



Michael C   (2002-02-12 11:20) [9]

пасибо Народ, буду пробовать эти варианты,
Очень выручили....
Пасибо за асёмблер тоже, но ...



McSimm   (2002-02-12 11:26) [10]

типа как у Romkin © мой вариант,
вариант пригодится, если надо получить весь список строк.

Никакой особой нагрузки на программу тут нет.
Вот хороший пример. Есть строка вида
"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, просто и изящно



Romkin   (2002-02-12 11:32) [11]

Ну до кучи, если строка длинная (метров 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;


При этом нарезки строки не производится, и выделения лишней памяти нет..



Michael C   (2002-02-12 11:44) [12]

Не сама строка, это 90 символов, но факт что строк таких эдак 500.



Michael C   (2002-02-12 12:31) [13]

Народ, оказывается есть проблема!!!!
Строк в файле 15000!, как убедиться что они все до единой обрабатываются???



Romkin   (2002-02-12 12:53) [14]

а ты их считай, в цикле



Johnmen   (2002-02-12 13:48) [15]

кем (чем) ? :)



oomneeq   (2002-02-12 13:57) [16]

2McSimm ©

Вместо
SL.Text := StringReplace(S, ",", #13#10,[rfReplaceAll]);
ecли заведомо нет пробелов
Проще писать
SL.CommaText := S;

Хотя не тестил, что из этого быстрее



McSimm   (2002-02-12 15:00) [17]

Не должна содержать пробелов, символов кавычек.
Для каких-то задач подойдет, но в общем случае - лучше через Text



vuk   (2002-02-12 15:09) [18]

Ну и я тоже влезу. :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;




Форум: "Основная";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.02.28;
Скачать: [xml.tar.bz2];




Наверх





Память: 0.75 MB
Время: 0.019 c
1-90541           cypher                2002-02-04 23:42  2002.02.28  
Контекстнгое меню проврдника


3-90519           Barmen                2002-02-05 12:20  2002.02.28  
У меня, господа программеры, вот такой вот вопросик...


1-90605           Roman_Tutov           2002-02-12 18:23  2002.02.28  
компонент DBGrid


1-90615           Alex Nazarenko        2002-02-12 07:33  2002.02.28  
Отчеты для матричного принтера


1-90548           Dave                  2002-02-11 06:59  2002.02.28  
Memo or RichEdit