|
Делфи. Ищу функцию типа Pos(s1,s2), но со стартом поиска не с 1 символа |
|
|
3 страниц
1 2 3 >
|
 |
Ответов
(1 - 35)
|
Jan 23 2012, 16:40
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(AHTOXA @ Jan 23 2012, 21:29)  StrPos: Что-то типа такого: ... А такая конструкция утечку памяти не создаст? Код Token := PChar(BigString); это вроде создаёт почти копию строки в динамической памяти, а следующая команда затрёт (?) оригинальный адрес. Кроме того, мне нужно работать в позициях оригинальной строки. То есть нужно эти адреса как-то преобразовывать в позиции.
Сообщение отредактировал GetSmart - Jan 23 2012, 16:40
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 23 2012, 16:41
|

Профессионал
    
Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581

|
Цитата(GetSmart @ Jan 23 2012, 19:50)  Существует ли такая? не катите бочку на профессионалов! такая функция есть! Цитата Delphi syntax:
function PosEx(const SubStr, S: string; Offset: Cardinal = 1): Integer;
Description
PosEx returns the index of SubStr in S, beginning the search at Offset. If Offset is 1 (default), PosEx is equivalent to Pos.
PosEx returns 0 if SubStr is not found, if Offset is greater than the length of S, or if Offset is less than 1. у вас что, Delphi без справочной системы? все же на раз находится там!
--------------------
Я бы взял частями... но мне надо сразу.
|
|
|
|
|
Jan 23 2012, 16:44
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(ARV @ Jan 23 2012, 21:41)  не катите бочку на профессионалов! такая функция есть! Код [Error] ????.pas(597): Undeclared identifier: 'PosEx' Что подключить надо? Цитата(ARV @ Jan 23 2012, 21:41)  у вас что, Delphi без справочной системы? все же на раз находится там! Есть Хелп. Этой функции там нет.
Сообщение отредактировал GetSmart - Jan 23 2012, 16:44
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 23 2012, 16:52
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(GetSmart @ Jan 23 2012, 22:40)  А такая конструкция утечку памяти не создаст? Код Token := PChar(BigString); это вроде создаёт почти копию строки в динамической памяти, а следующая команда затрёт (?) оригинальный адрес. Нет, это просто преобразование типов, никаких копий. Цитата(GetSmart @ Jan 23 2012, 22:40)  Кроме того, мне нужно работать в позициях оригинальной строки. То есть нужно эти адреса как-то преобразовывать в позиции. Элементарно: Код Token := PChar(BigString); Start = Token; // Запомним начало Token := StrPos(Token, PChar(SubStr)); IndexInString := Token - Start + 1; // Вычислим индекс в строке
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Jan 23 2012, 16:58
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(ARV @ Jan 23 2012, 21:46)  а что за версия Delphi у вас такая?! подключать надо StrUtils. Делфи 5. StrUtils не найден. Для начала попробую поискать. Цитата(AHTOXA @ Jan 23 2012, 21:52)  Нет, это просто преобразование типов, никаких копий. Не может быть. Явно создаётся копия с #0 в конце строки. Даже указатель индивидуальный, явно будет отличаться от оригинальной строки. Цитата(AHTOXA @ Jan 23 2012, 21:52)  Элементарно: Ок. А удалять Token я сам потом должен? Потому как, когда один раз, то не ... жалко, а когда миллион раз, то надо об этом 7 раз подумать. ЗЫ. Самое главно, что хотелось бы иметь допустимость #0 байт внутри строк и при этом нормальной работы. Так что Сишные строки - это самый крайний ущербный вариант. PosEx запустить было бы идеально.
Сообщение отредактировал GetSmart - Jan 23 2012, 17:01
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 23 2012, 16:59
|

Профессионал
    
Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581

|
вы бы еще 3-ю версию юзали! самая ходовая 7-я версия - в ней есть очень много всего хорошего, и очень мало лишнего, что потом прилипло... рекомендую обновиться. еще рекомендую найти и скачать библиотеку JVCL - отличная бесплатная коллекция на все случаи жизни с открытыми исходниками. если строки у вас "короткие", т.е. не WideString, то можно колупаться с посимвольным разбором так: Код var strptr : pchar; i : integer; begin strptr = @my_str[1]; // и далее strptr[0] - 1-й символ, как в Си. strptr можно менять, как угодно - все как в Си, только внутри my_str не будет 0 на конце. // strptr в функциях полностью "совместим" с типом string, т.е. можно так: i := Pos('тра-та-та', strptr); inc(strptr, i+1); // и так далее end;
--------------------
Я бы взял частями... но мне надо сразу.
|
|
|
|
|
Jan 23 2012, 17:10
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(GetSmart @ Jan 23 2012, 22:58)  Не может быть. Явно создаётся копия с #0 в конце строки. Даже указатель индивидуальный, явно будет отличаться от оригинальной строки. Да нет же  Это просто указатель на char. Мы его наводим на первый символ строки. И начинаем по ней елозить. Всё. Цитата Ок. А удалять Token я сам потом должен? Нет. Это просто указатель в середину строки. (Начинаю чувствовать себя попугаем  ) Цитата Самое главно, что хотелось бы иметь допустимость #0 байт внутри строк и при этом нормальной работы. Так что Сишные строки - это самый крайний ущербный вариант. PosEx запустить было бы идеально. Насчёт нуля - не уверен, надо проверять. PosEx могу запостить, но только завтра
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Jan 23 2012, 17:23
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(AHTOXA @ Jan 23 2012, 22:10)  Да нет же  Это просто указатель на char. Мы его наводим на первый символ строки. И начинаем по ней елозить. Всё. А откуда берётся #0 в конце этой же строки, если его там не было? Цитата(AHTOXA @ Jan 23 2012, 22:15)  Вот, нашёл, strutils специально для D5: тыц!Скопировал к себе в проект только одну функцию. Скомпилилась. Последний вопрос - она точно будет нормально работать со строками с #0-символами, разбросанными по строке? Дальше первого #0 будет продолжаться поиск? Я чего-то сильно сильно сомневаюсь
Сообщение отредактировал GetSmart - Jan 23 2012, 17:27
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 23 2012, 17:30
|
Местный
  
Группа: Свой
Сообщений: 352
Регистрация: 13-08-11
Из: Воронеж
Пользователь №: 66 710

|
Цитата(GetSmart @ Jan 23 2012, 19:27)  Но хотелось бы не делать лишней работы, и узнать заранее что надо, а что не надо. Моему дилетантскому имху кажется, что при процитированном подходе в первую очередь следует прислушаться к неоднократным советам ARV, а потом уже копать дальше при необходимости. ЗЫ пока набирал пост, вы уже вняли голосу разума и методологически верной стратегии
Сообщение отредактировал _Ivana - Jan 23 2012, 17:32
|
|
|
|
|
Jan 23 2012, 17:32
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(GetSmart @ Jan 23 2012, 23:23)  А откуда берётся #0 в конце этой же строки, если его там не было? Вот тут не знаю. Возможно он в string предусмотрен изначально. Цитата(GetSmart @ Jan 23 2012, 23:23)  Последний вопрос - она точно будет нормально работать со строками с #0-символами, разбросанными по строке? Дальше первого #0 будет продолжаться поиск? Если через StrPos - то вряд ли. Иначе как он определит конец строки? Имхо, проще написать свою функцию
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Jan 23 2012, 17:53
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(ARV @ Jan 23 2012, 21:41)  не катите бочку на профессионалов! такая функция есть! А не подскажете, PosEx из 7-й делфи будет работать со строками с #0 в середине? Принимаются - Да, Нет, Не знаю  Upd И ещё вопрос: На страницах HTML 100% гарантируется отсутствие символов #0 ?
Сообщение отредактировал GetSmart - Jan 23 2012, 18:10
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 24 2012, 02:19
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Цитата Принимаются - Да, Нет, Не знаю я выбираю вариант "Не знаю" Но позволю себе немного размышлений... Кажется формат хранения строк в Delphi отличается от сишного тем, что #0 не должен являться признаком конца строки. Вмместо этого длилна строки известна заранее(кажется хранится в первом байте). Т.е. при использовании типа string - проблемы с нулем скорее всего быть не должно. В конце концов несложный эксперимент раз и на всегда прояснит ситуацию. Но Delphi сейчас ставить как-то не хочется )
--------------------
The truth is out there...
|
|
|
|
|
Jan 24 2012, 03:33
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(GetSmart @ Jan 23 2012, 23:53)  А не подскажете, PosEx из 7-й делфи будет работать со строками с #0 в середине? Принимаются - Да, Нет, Не знаю  Насчёт седьмой - не скажу, а вот из десятой - будет. Вот оно: CODE (* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1 * * The implementation of function PosEx is subject to the * Mozilla Public License Version 1.1 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Fastcode * * The Initial Developer of the Original Code is Fastcode * * Portions created by the Initial Developer are Copyright © 2002-2004 * the Initial Developer. All Rights Reserved. * * Contributor(s): Aleksandr Sharahov * * ***** END LICENSE BLOCK ***** *) function PosEx(const SubStr, S: string; Offset: Integer = 1): Integer; asm test eax, eax jz @Nil test edx, edx jz @Nil dec ecx jl @Nil push esi push ebx mov esi, [edx-4] //Length(Str) mov ebx, [eax-4] //Length(Substr) sub esi, ecx //effective length of Str add edx, ecx //addr of the first char at starting position cmp esi, ebx jl @Past //jump if EffectiveLength(Str)<Length(Substr) test ebx, ebx jle @Past //jump if Length(Substr)<=0 add esp, -12 add ebx, -1 //Length(Substr)-1 add esi, edx //addr of the terminator add edx, ebx //addr of the last char at starting position mov [esp+8], esi //save addr of the terminator add eax, ebx //addr of the last char of Substr sub ecx, edx //-@Str[Length(Substr)] neg ebx //-(Length(Substr)-1) mov [esp+4], ecx //save -@Str[Length(Substr)] mov [esp], ebx //save -(Length(Substr)-1) movzx ecx, byte ptr [eax] //the last char of Substr @Loop: cmp cl, [edx] jz @Test0 @AfterTest0: cmp cl, [edx+1] jz @TestT @AfterTestT: add edx, 4 cmp edx, [esp+8] jb @Continue @EndLoop: add edx, -2 cmp edx, [esp+8] jb @Loop @Exit: add esp, 12 @Past: pop ebx pop esi @Nil: xor eax, eax ret @Continue: cmp cl, [edx-2] jz @Test2 cmp cl, [edx-1] jnz @Loop @Test1: add edx, 1 @Test2: add edx, -2 @Test0: add edx, -1 @TestT: mov esi, [esp] test esi, esi jz @Found @String: movzx ebx, word ptr [esi+eax] cmp bx, word ptr [esi+edx+1] jnz @AfterTestT cmp esi, -2 jge @Found movzx ebx, word ptr [esi+eax+2] cmp bx, word ptr [esi+edx+3] jnz @AfterTestT add esi, 4 jl @String @Found: mov eax, [esp+4] add edx, 2 cmp edx, [esp+8] ja @Exit add esp, 12 add eax, edx pop ebx pop esi end;
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Jan 24 2012, 06:20
|

Профессионал
    
Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581

|
1. функции, работающие со строками ПАСКАЛЕВСКОГО типа (без нуля в конце) могут содержать в своей середине сколько угодно нулей. в связи с этим PosEx работать будет. 2. увидел - мелькнуло слово HTML... тайна покрыта мраком, но если вы парсите HTML, то снова порекомендую вам JVCL - там в комплекте есть много вещей, которые вам помогут, в том числе функции, которые почти готовы для того, чтобы искать и находить в HTML-тексте нужные теги и т.п. Вы удивитесь: как много в этой библиотеке есть готовых решений!  3. если вдруг вам нужно делать поиск и замену, то для этого так же есть готовая библиотечная функция (начиная с 7 версии). очень удобно.
--------------------
Я бы взял частями... но мне надо сразу.
|
|
|
|
|
Jan 25 2012, 07:45
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(AHTOXA @ Jan 23 2012, 22:32)  Вот тут не знаю. Возможно он в string предусмотрен изначально. Действительно, за последним символом Делфа намеренно ставит #0. Обрезая строку на 1 символ несколько раз, на месте обрезанного появляется ноль. А уже за нулём может быть мусор. Недокументированная фича? PosEx из десятки отлично работает. Тем более на асме. Самый fast.
Сообщение отредактировал GetSmart - Jan 25 2012, 08:42
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 25 2012, 09:11
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(_Pasha @ Jan 25 2012, 13:56)  Значит, с нулём в конце надо уважительно быть , вставлять его в середину и прочие фокусы недопустимы. Кстати, утечки при освобождении строки могут быть, если для определения ее длины используется strlen(). Подробностей не помню. Не. В делфе не так. ИМХО этот ноль - просто костыль для си-совместимости строк, которые могут выводиться куда-то функциями (винды) с сишными аргументами. Например в Application.MessageBox(). Там и преобразование адреса сделано через PChar(name). Хотя раньше из-за этого нуля я думал что создаётся временная копия. Этот string ещё как-то криво типизируется в 5-ой делфе. Поставил опцию H-, оно заругалось, что в компоненте тип string, а у меня в проге ShortString (хотя указан string). Далее я поменял все string в проге на AnsiString. Опять ругается, что в компоненте string, а у меня в проге AnsiString. Хотя вроде не должен.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 26 2012, 05:32
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(GetSmart @ Jan 25 2012, 13:45)  Недокументированная фича? Я где-то про это читал, так что немножко документированная  Но где читал - не помню. Цитата(GetSmart @ Jan 25 2012, 15:11)  Не. В делфе не так. ИМХО этот ноль - просто костыль для си-совместимости строк, которые могут выводиться куда-то функциями (винды) с сишными аргументами. Именно. Дельфя обеспечивает ноль на позиции (длина строки + 1). При этом нули в самой строке вполне допустимы (но они обманут функции, принимающие в качестве аргумента PChar).
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|