Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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;



Страницы: 1 вся ветка

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

Наверх




Память: 0.49 MB
Время: 0.004 c
3-90448
andrucco
2002-02-01 13:34
2002.02.28
Кривая БД в mdb файле


3-90512
tow
2002-02-04 10:50
2002.02.28
Базы данных


3-90494
dymka
2002-02-04 12:42
2002.02.28
тип TIME в IB6


3-90503
Demon ltd
2002-02-04 20:56
2002.02.28
Из db в dbf


3-90461
Rad
2002-01-31 19:15
2002.02.28
Как выяснить размерность поля Numeric?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский