Вот 2 функции которыми я очень часто пользуюсь - они выделяют из строки подстроку, которая находится до или после ключевого словаю Задача надо сказать частая, например есть строка:
"Total-2.00$"
Нижеприведенные функции позволяют выделить из строки логические элементы:
Code: |
functionGetBefore(substr, str:string):string; {©Drkb v.3(2007): www. drkb . ru, ®Vit (Vitaly Nevzorov) - nevzorov @ yahoo.com} begin if pos(substr,str)>0then result:=copy(str,1,pos(substr,str)-1) else result:=''; end;
functionGetAfter(substr, str:string):string; {©Drkb v.3(2007): www.drk b. ru, ®Vit (Vitaly Nevzorov) - nevzorov @ yahoo.com} begin if pos(substr,str)>0then result:=copy(str,pos(substr,str)+length(substr),length(str)) else result:=''; end; |
Примеры:
1) Найти название параметра (оно находится до символа "-"):
GetBefore('-', 'Total-2.00$') // Результат будет "Total"
2) Найти сумму денег (оно находится после символа "-"):
GetAfter('-', 'Total-2.00$') // Результат будет "2.00$"
3) Найти сумму денег без знака доллара и остатка строки(оно находится после символа "-", но до символа "$"):
GetBefore('$',GetAfter('-', 'Total-2.00$ (общая сумма)') // Результат будет "2.00"
Автор:Vit
- Подробности
- Родительская категория: Работа со строками
- Категория: Разбор строки, выделение элементов, поиск
Code: |
{ **** UBPFD *********** by delphibase.endimus.com **** >> Делит строку аStr на три строки St1,St2,St3 длиной Long1,Long2,Long3
Делит строку аStr на три строки St1,St2,St3 длиной Long1,Long2,Long3 соответственно или меньше в зависимости от длины исходной строки.
Зависимости: ??? Автор: Сергей, Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра., Краснодар Copyright: VIP BANK
***************************************************** }
procedure DivPart(aStr: string; var St1, St2, St3: string; Long1, Long2, Long3: byte); var i, pos, Long: byte; begin St1 := ''; St2 := ''; St3 := ''; aStr := Trim(aStr); Long := Length(aStr); if Long <= Long1 then begin St1 := aStr; Exit end; Pos := Long1; for i := 1to Long1 + 1do if aStr[i] = ' 'then Pos := i; St1 := TrimRight(Copy(aStr, 1, Pos)); Delete(aStr, 1, Pos); aStr := TrimLeft(aStr); Long := Length(aStr); if Long <= Long2 then begin St2 := aStr; Exit end; Pos := Long2; for i := 1to Long2 + 1do if aStr[i] = ' 'then Pos := i; St2 := TrimRight(Copy(aStr, 1, Pos)); St3 := Trim(Copy(aStr, Pos + 1, Long3)) end; |
©Drkb::00841
Code: |
{ **** UBPFD *********** by delphibase.endimus**** >> Разбивка строки на подстроки с использованием заданного разделителя
Параметры: Str: WideString - Строка для разбивки Delimiter: String - Разделитель подстрок с строке Str Результат: TStringList: Список найденных подстрок
Зависимости: System, Sysutils, Classes Автор: Stoma, stoma @ bitex.bg Copyright: Собственная разработка
***************************************************** }
function Tokenize(Str: WideString; Delimiter: string): TStringList; var tmpStrList: TStringList; tmpString, tmpVal: WideString; DelimPos: LongInt; begin tmpStrList := TStringList.Create; TmpString := Str; DelimPos := 1; while DelimPos > 0do begin DelimPos := LastDelimiter(Delimiter, TmpString); tmpVal := Copy(TmpString, DelimPos + 1, Length(TmpString)); if tmpVal <> ''then tmpStrList.Add(UpperCase(tmpVal)); Delete(TmpString, DelimPos, Length(TmpString)); end; Tokenize := tmpStrList; end; Пример использования:
function TForm1.GetDirNames(FullPath: string): TStringList; begin GetDirNames := Tokenize(FullPath, '\'); end; |
Code: |
procedure Explode(var a: arrayofstring; Border, S: string); var S2: string; i: Integer; begin i := 0; S2 := S + Border; repeat a[i] := Copy(S2, 0,Pos(Border, S2) - 1); Delete(S2, 1,Length(a[i] + Border)); Inc(i); until S2 = ''; end;
// How to use it: // Und hier ein Beispiel zur Verwendung:
procedure TForm1.Button1Click(Sender: TObject); var S: string; A: arrayofString; begin S := 'Ein Text durch Leerzeichen getrennt'; SetLength(A, 10); Explode(A, ' ', S); ShowMessage(A[0] + ' ' + A[1] + ' ' + A[2] + ' ' + A[3] + ' ' + A[4]); end;
|
- Подробности
- Родительская категория: Работа со строками
- Категория: Разбор строки, выделение элементов, поиск
Code: |
unit awMachMask; // © Alexandr Petrovich Sysoev
interface
uses Classes;
///////////////////////////////////////////////////// Работа со списком шаблонов // Функции предназначены для сопоставления текстов (имен файлов) на // соответствие заданному шаблону или списку шаблонов. // Обычно используется для посторения простых фильтров, например аналогичных // файловым фильтрам программы Total Commander. // // Каждый шаблон аналогичен шаблону имен файлов в MS-DOS и MS Windows, // т.е. может включать "шаблонные" символы '*' и '?' и не может включать // символ '|'. // Любой шаблон может быть заключен в двойные кавычки ('''), при этом двойные // кавычки имеющиеся в шаблоне должны быть удвоены. Если шаблон включает // символы ';' или ' ' (пробел) то он обязательно должен быть заключен в // двойные кавычки. // В списке, шаблоны разделяются символом ';'. // За первым списком шаблонов, может следовать символ '|', за которым может // следовать второй список. // Текст (имя файла) будет считаться соответствующим списку шаблонов только // если он соответствует хотя бы одному шаблону из первого списка, // и не соответствует ни одному шаблону из второго списка. // Если первый список пуст, то подразумевается '*' // // Формальное описание синтаксиса списка шаблонов: // // Полный список шаблонов :: [<список включаемых шаблонов>]['|'<список исключаемых шаблонов>] // список включаемых шаблонов :: <список шаблонов> // список исключаемых шаблонов :: <список шаблонов> // список шаблонов :: <шаблон>[';'<шаблон>] // шаблон :: шаблон аналогичный шаблону имен файлов в // MS-DOS и MS Windows, т.е. может включать // "шаблонные" символы '*' и '?' и не может // включать символ '|'. Шаблон может быть // заключен в двойные кавычки (''') при этом // двойные кавычки имеющиеся в шаблоне должны // быть удвоены. Если шаблон включает символы // ';' или ' ' (пробел) то он // обязательно должен быть заключен в двойные // кавычки. // // Например: // '*.ini;*.wav' - соответствует любым файлам с расшиениями 'ini' // или 'wav' // '*.*|*.exe' - соответствует любым файлам, кроме файлов с // расширением 'EXE' // '*.mp3;*.wav|?.*;??.*' - соответствует любым файлам с расшиениями 'mp3' // и 'wav' за исключением файлов у которых имя // состоит из одного или двух символов. // '|awString.*' - соответствует любым файлам за исключением файлов // с именем awString и любым расширением. //
Function IsMatchMask (aText, aMask :pChar ) :Boolean; overload; Function IsMatchMask (aText, aMask :String; aFileNameMode :Boolean =True) :Boolean; overload; // Выполняют сопоставление текста aText с одним шаблоном aMask. // Возвращает True если сопоставление выполнено успешно, т.е. текст // aText соответствует шаблону aMask. // Если aFileNameModd=True, то объект используется для сопоставления // имен файлов с шаблоном. А именно, в этом случае, если aText не // содержит символа '.' то он добавляется в конец. Это необходимо для // того, чтобы файлы без расширений соответствовали например шаблону '*.*'
Function IsMatchMaskList (aText, aMaskList :String; aFileNameMode :Boolean =True): Boolean; // Выполняет сопоставление текста aText со списком шаблонов aMaskList. // Возвращает True если сопоставление выполнено успешно, т.е. текст // aText соответствует списку шаблонов aMaskList. // Если aFileNameModd=True, то объект используется для сопоставления // имен файлов с шаблоном. А именно, в этом случае, если aText не // содержит символа '.' то он добавляется в конец. Это необходимо для // того, чтобы файлы без расширений соответствовали например шаблону '*.*' // // Замечание, если требуется проверка сопоставления нескольких строк одному // списку шаблонов, эффективнее будет воспользоваться объектом tMatchMaskList.
Type tMatchMaskList = class(tObject) Private fMaskList :String; fCaseSensitive :Boolean; fFileNameMode :Boolean;
fPrepared :Boolean; fIncludeMasks :tStringList; fExcludeMasks :tStringList;
procedure SetMaskList (v :String ); procedure SetCaseSensitive (v :Boolean);
Public constructor Create (Const aMaskList :String =''); // Создает объект. Если задан параметр aMaskList, то он присваивается // свойству MaskList.
destructor Destroy; override; // Разрушает объект
procedure PrepareMasks; // Осуществляет компиляцию списка шаблонов во внутреннюю структуру // используемую при сопоставлении текста. // Вызов данного метода не является обязательным и при необходимости // будет вызван автоматически.
Function IsMatch (aText :String) :Boolean; // Выполняет сопоставление текста aText со списком шаблонов MaskList. // Возвращает True если сопоставление выполнено успешно, т.е. текст // aText соответствует списку шаблонов MaskList.
Property MaskList :StringRead fMaskList Write SetMaskList ; // Списко шаблонов используемый для сопоставления с текстом
Property CaseSensitive :Boolean Read fCaseSensitive Write SetCaseSensitive default False; // Если False (по умолчанию), то при сопоставлении текста будет // регистр символов не будет учитываться. // Иначе, если True, сопоставление будет проводиться с учетом регистра.
Property FileNameMode :Boolean Read fFileNameMode Write fFileNameMode default True; // Если True (по умолчанию), то объект используется для сопоставления // имен файлов с шаблоном. А именно, в этом случае, если aText не // содержит символа '.' то он добавляется в конец. Это необходимо для // того, чтобы файлы без расширений соответствовали например шаблону '*.*'
End;
implementation
uses SysUtils ;
Function IsMatchMask (aText, aMask :pChar ) :Boolean; overload; begin Result := False; While True Dobegin Case aMask^ of '*' : // соответствует любому числу любых символов кроме конца строки begin // переместиться на очередной символ шаблона, при этом, подряд // идущие '*' эквивалентны одному, поэтому пропуск всех '*' repeat Inc(aMask); Until (aMask^<>'*'); // если за '*' следует любой символ кроме '?' то он должен совпасть // с символом в тексте. т.е. нужно пропустить все не совпадающие, // но не далее конца строки If aMask^ <> '?'then While (aText^ <> #0) And (aText^ <> aMask^) Do Inc(aText);
If aText^ <> #0Thenbegin// не конец строки, значит совпал символ // '*' 'жадный' шаблон поэтому попробуем отдать совпавший символ // ему. т.е. проверить совпадение продолжения строки с шаблоном, // начиная с того-же '*'. если продолжение совпадает, то If IsMatchMask (aText+1, aMask-1) Then Break; // это СОВПАДЕНИЕ // продолжение не совпало, значит считаем что здесь закончилось // соответствие '*'. Продолжим сопоставление со следующего // символа шаблона Inc(aMask); Inc(aText); // иначе переходим к следующему символу End ElseIf (aMask^ = #0) Then// конец строки и конец шаблона Break // это СОВПАДЕНИЕ Else// конец строки но не конец шаблона Exit // это НЕ СОВПАДЕНИЕ End;
'?' : // соответствует любому кроме конца строки If (aText^ = #0) Then// конец строки Exit // это НЕ СОВПАДЕНИЕ Elsebegin// иначе Inc(aMask); Inc(aText); // иначе переходим к следующему символу End;
Else// символ в шаблоне должен совпасть с символом в строке If aMask^ <> aText^ Then// символы не совпали - Exit // это НЕ СОВПАДЕНИЕ Elsebegin// совпал очередной символ If (aMask^ = #0) Then// совпавший символ последний - Break; // это СОВПАДЕНИЕ Inc(aMask); Inc(aText); // иначе переходим к следующему символу End; End; End; Result := True; End;
Function IsMatchMask (aText, aMask :String; aFileNameMode :Boolean =True) :Boolean; overload; begin If aFileNameMode And (Pos('.',aText)=0) then aText := aText+'.'; Result := IsMatchMask(pChar(aText),pChar(aMask)); End;
Function IsMatchMaskList (aText, aMaskList :String; aFileNameMode :Boolean =True) :Boolean; begin With tMatchMaskList.Create(aMaskList) Dotry FileNameMode := aFileNameMode; Result := IsMatch(aText); finally Free; End; End;
/////////////////////////////////////////////////////////// tFileMask
procedure tMatchMaskList.SetMaskList (v :String ); begin If fMaskList = v Then Exit; fMaskList := v; fPrepared := False; End;
procedure tMatchMaskList.SetCaseSensitive (v :Boolean); begin If fCaseSensitive = v Then Exit; fCaseSensitive := v; fPrepared := False; End;
constructor tMatchMaskList.Create (Const aMaskList :String); begin MaskList := aMaskList; fFileNameMode := True;
fIncludeMasks := TStringList.Create; With fIncludeMasks Dobegin Delimiter := ';'; // Sorted := True; // Duplicates := dupIgnore; End;
fExcludeMasks := tStringList.Create; With fExcludeMasks Dobegin Delimiter := ';'; // Sorted := True; // Duplicates := dupIgnore; End; End;
destructor tMatchMaskList.Destroy; begin fIncludeMasks.Free; fExcludeMasks.Free; End;
procedure tMatchMaskList.PrepareMasks;
procedure CleanList(l :tStrings); var i :Integer; begin For i := l.Count-1downto0DoIf l[i] = ''then l.Delete(i); End;
var s :String; i :Integer; begin If fPrepared Then Exit;
If CaseSensitive Then s := MaskList Else s := UpperCase(MaskList);
i := Pos('|',s); If i = 0Thenbegin fIncludeMasks.DelimitedText := s; fExcludeMasks.DelimitedText := ''; End Elsebegin fIncludeMasks.DelimitedText := Copy(s,1,i-1); fExcludeMasks.DelimitedText := Copy(s,i+1,MaxInt); End;
CleanList(fIncludeMasks); CleanList(fExcludeMasks);
// если список включаемых шаблонов пуст а // список исключаемых шаблонов не пуст, то // имеется ввиду что список включаемых шаблонов равен <все файлы> If (fIncludeMasks.Count = 0) And (fExcludeMasks.Count <> 0) Then fIncludeMasks.Add('*');
fPrepared := True; End;
Function tMatchMaskList.IsMatch (aText :String) :Boolean; var i :Integer; begin Result := False; If aText = ''then Exit; IfNot CaseSensitive Then aText := UpperCase(aText); If FileNameMode And (Pos('.',aText)=0) then aText := aText+'.'; IfNot fPrepared Then PrepareMasks;
// поиск в списке "включаемых" масок до первого совпадения For i := 0To fIncludeMasks.Count-1Do If IsMatchMask(PChar(aText),PChar(fIncludeMasks[i])) Thenbegin Result := True; Break; End;
// если совпадение найдено, надо проверить по списку "исключаемых" If Result Then For i := 0To fExcludeMasks.Count-1Do If IsMatchMask(PChar(aText),PChar(fExcludeMasks[i])) Thenbegin Result := False; Break; End; End;
end. |
Автор:Петрович
Взято из https://forum.sources
- Подробности
- Родительская категория: Работа со строками
- Категория: Разбор строки, выделение элементов, поиск
Автор: Сергей Шамайтис
Code: |
function ReplaceSub(str, sub1, sub2: string): string; var aPos: Integer; rslt: string; begin aPos := Pos(sub1, str); rslt := ''; while (aPos <> 0) do begin rslt := rslt + Copy(str, 1, aPos - 1) + sub2; Delete(str, 1, aPos + Length(sub1) - 1); aPos := Pos(sub1, str); end; Result := rslt + str; end; |
Code: |
function ReplaceStr(const S, Srch, Replace: string): string; {замена подстроки в строке} var I: Integer; Source: string; begin Source := S; Result := ''; repeat I := Pos(Srch, Source); if I > 0then begin Result := Result + Copy(Source, 1, I - 1) + Replace; Source := Copy(Source, I + Length(Srch), MaxInt); end else Result := Result + Source; until I< = 0; end; |
https://delphiworld.narod.
DelphiWorld 6.0
Code: |
{ **** UBPFD *********** by delphibase.endimus **** >> Замена в строке всех вхождений одной подстроки, на другую
Зависимости: - Автор: Евгений Валяев (RhinoFC), Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра., ICQ:55263922, Новосибирск Copyright: RhinoFC
***************************************************** }
function StrReplace(const Str, Str1, Str2: string): string; // str - исходная строка // str1 - подстрока, подлежащая замене // str2 - заменяющая строка var P, L: Integer; begin Result := str; L := Length(Str1); repeat P := Pos(Str1, Result); // ищем подстроку if P > 0then begin Delete(Result, P, L); // удаляем ее Insert(Str2, Result, P); // вставляем новую end; until P = 0; end;
|
А стандартная функция StringReplace чем не устраивает?
Автор:Vit
- Подробности
- Родительская категория: Работа со строками
- Категория: Разбор строки, выделение элементов, поиск
Code: |
{ **** UBPFD *********** by delphibase.endimus**** >> Нахождение последнего вхождения подстроки в строку
Функция возвращает начало последнего вхождения подстроки FindS в строку SrcS, т.е. первое с конца. Если возвращает ноль, то подстрока не найдена. Можно использовать в текстовых редакторах при поиске текста вверх от курсора ввода.
Зависимости: System Автор: Fenik, chook_nu @ uraltc.ru, Новоуральск Copyright: Автор: Федоровских Николай
***************************************************** }
function PosR2L(const FindS, SrcS: string): Integer; {Функция возвращает начало последнего вхождения подстроки FindS в строку SrcS, т.е. первое с конца. Если возвращает ноль, то подстрока не найдена. Можно использовать в текстовых редакторах при поиске текста вверх от курсора ввода.}
function InvertS(const S: string): string; {Инверсия строки S} var i, Len: Integer; begin Len := Length(S); SetLength(Result, Len); for i := 1to Len do Result[i] := S[Len - i + 1]; end;
var ps: Integer; begin {Например: нужно найти последнее вхождение строки 'ро' в строке 'пирожок в коробке'. Инвертируем обе строки и получаем 'ор' и 'екборок в кожорип', а затем ищем первое вхождение с помощью стандартной функции Pos(Substr, S: string): string; Если подстрока Substr есть в строке S, то эта функция возвращает позицию первого вхождения, а иначе возвращает ноль.} ps := Pos(InvertS(FindS), InvertS(SrcS)); {Если подстрока найдена определяем её истинное положение в строке, иначе возвращаем ноль} if ps <> 0then Result := Length(SrcS) - Length(FindS) - ps + 2 else Result := 0; end; Пример использования:
p := PosR2L('са', 'Мой сапог догнал самолёт.'); // p:=18; |
Code: |
{ Letzte Position von SubStr in S ermitteln. Returns the last occurence of SubStr in S. }
function LastPos(SubStr, S: string): Integer; var Found, Len, Pos: integer; begin Pos := Length(S); Len := Length(SubStr); Found := 0; while (Pos > 0) and (Found = 0) do begin if Copy(S, Pos, Len) = SubStr then Found := Pos; Dec(Pos); end; LastPos := Found; end;
|
Code: |
// by Manuel Wiersch
function LastPos(const SubStr: AnsiString; const S: AnsiString): LongInt; asm TEST EAX,EAX // EAX auf 0 prufen (d.h. SubStr = nil) JE @@noWork // wenn EAX = 0 dann Sprung zu noWork TEST EDX,EDX // Test ob S = nil JE @@stringEmpty // bei Erfolg -> Sprung zum Label 'stringEmpty' PUSH EBX PUSH ESI PUSH EDI // Register auf dem Stack sichern Grund: OH // OH: "In einer asm-Anweisung mu? der Inhalt // der Register EDI, ESI, ESP, EBP und EBX // erhalten bleiben (dh. vorher auf dem Stack // speichern) MOV ESI, EAX // ESI = Sourceindex -> Adresse vom SubStr MOV EDI, EDX // EDI = Destinationindex -> Adresse von S MOV ECX,[EDI-4] // Lange von S ins Zahlregister MOV EDX,[ESI-4] // Lange des SubStr in EDX DEC EDX // Length(SubStr) - 1 JS @@fail // Vorzeichenbedingter Sprung (JumpIfSign) // d.h. (EDX < 0) -> Sprung zu 'fail' STD; // SetDirectionFlag -> Stringroutinen von hinten // abarbeiten ADD ESI, EDX // Pointer auf das letzte Zeichen vom SubStr ADD EDI, ECX DEC EDI // Pointer auf das letzte Zeichen von S MOV AL, [ESI] // letztes Zeichen des SubStr in AL laden DEC ESI // Pointer auf das vorletzte Zeichen setzen. SUB ECX, EDX // Anzahl der Stringdurchlaufe // = Length(s) - Length(substr) + 1 JLE @@fail // Sprung zu 'fail' wenn ECX <= 0 @@loop: REPNE SCASB // Wdh. solange ungleich (repeat while not equal) // scan string for byte JNE @@fail MOV EBX,ECX { Zahleregister, ESI und EDI sichern, da nun der Vergleich durchgefuhrt wird ob die nachfolgenden Zeichen von SubStr in S vorhanden sind } PUSH ESI PUSH EDI MOV ECX,EDX // Lange des SubStrings in ECX REPE CMPSB // Solange (ECX > 0) und (Compare string fo byte) // dh. solange S[i] = SubStr[i] POP EDI POP ESI // alten Source- und Destinationpointer vom Stack holen JE @@found // Und schon haben wir den Index da ECX = 0 // dh. alle Zeichen wurden gefunden MOV ECX, EBX // ECX wieder auf alte Anzahl setzen und JMP @@loop // Start bei 'loop' @@fail: XOR EAX,EAX // EAX auf 0 setzen JMP @@exit @@stringEmpty: XOR EAX,EAX JMP @@noWork @@found: MOV EAX, EBX // in EBX steht nun der aktuelle Index INC EAX // um 1 erhohen, um die Position des 1. Zeichens zu // bekommen @@exit: POP EDI POP ESI POP EBX @@noWork: CLD; // DirectionFlag loschen end; |
- Подробности
- Родительская категория: Работа со строками
- Категория: Разбор строки, выделение элементов, поиск
Code: |
//----------------------------------------------------------------------------- // Name: cnsSmartPos // Author: Com-N-Sense // Date: // Purpose: Find a substring in a string starting from any position in the string. // Params: SubStr - a substring for search. // S - the source string to search within // StartPos - the index position to start the search. // Result: Integer - the position of the substring, // zero - if the substring was not found // Remarks: This is the original Delphi "Pos" function modified to support // the start pos parameter. //----------------------------------------------------------------------------- function SmartPosAsm(const substr : AnsiString; const s : AnsiString; StartPos : Cardinal) : Integer; type StrRec = packedrecord allocSiz: Longint; refCnt: Longint; length: Longint; end; const skew = sizeof(StrRec); asm { ->EAX Pointer to substr } { EDX Pointer to string } { <-EAX Position of substr in s or 0 } TEST EAX,EAX JE @@noWork
TEST EDX,EDX JE @@stringEmpty
PUSH EBX PUSH ESI PUSH EDI
MOV ESI,EAX { Point ESI to substr } MOV EDI,EDX { Point EDI to s }
MOV EAX,ECX MOV ECX,[EDI-skew].StrRec.length { ECX = Length(s) } ADD EDI,EAX SUB ECX,EAX
PUSH EDI { remember s position to calculate index }
MOV EDX,[ESI-skew].StrRec.length { EDX = Length(substr) DEC EDX { EDX = Length(substr) - 1 } JS @@fail { < 0 ? return 0 } MOV AL,[ESI] { AL = first char of substr } INC ESI { Point ESI to 2'nd char of substr }
SUB ECX,EDX { #positions in s to look at } { = Length(s) - Length(substr) + 1 } JLE @@fail @@loop: REPNE SCASB JNE @@fail MOV EBX,ECX { save outer loop counter } PUSH ESI { save outer loop substr pointer } PUSH EDI { save outer loop s pointer }
MOV ECX,EDX REPE CMPSB POP EDI { restore outer loop s pointer } POP ESI { restore outer loop substr pointer } JE @@found MOV ECX,EBX { restore outer loop counter } JMP @@loop
@@fail: POP EDX { get rid of saved s pointer } XOR EAX,EAX JMP @@exit
@@stringEmpty: XOR EAX,EAX JMP @@noWork
@@found: POP EDX { restore pointer to first char of s } MOV EAX,EDI { EDI points of char after match } SUB EAX,EDX { the difference is the correct index } @@exit: POP EDI POP ESI POP EBX @@noWork: end; //SmartPosAsm
function cnsSmartPos(const substr : AnsiString; const s : AnsiString; StartPos : Cardinal) : Integer; begin dec(StartPos); Result := SmartPosAsm(SubStr,S,StartPos); if Result > 0then Result := Result + StartPos; end; //cnsSmartPos |
Круто конечно, но есть стандартная функция:
function PosEx(const SubStr, S: string; Offset: Cardinal = 1): Integer;
Автор:Vit
Code: |
{ **** UBPFD *********** by delphibase.endimus **** >> Поиск подстроки в строке с заданной позиции
S - строка, в которой искать SubStr - образец fromPos - с какой позиции Все на асемблере, принцип простой - ищется первый символ, затем часть строки сравнивается с образцом начиная с этого символа Если образец не найден, возвращает 0 Если найден - номер первого символа вхождения
Зависимости: Нету их! Автор: Romkin, romkin @ pochtamt.ru, Москва Copyright: Модернизированная функция из SysUtils
***************************************************** }
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; |
Code: |
{ **** UBPFD *********** by delphibase.endimus **** >> Поиск подстроки в строке с заданной позиции (стандартный вариант)
Вроде работает Substr - подстрока, S - строка, fromPos - с какой позиции искать Если вхождение не найдено, возвращает 0 Ограничения - как для ansiStrPos
Зависимости: SysUtils Автор: Romkin, romkin @ pochtamt.ru, Москва Copyright: Romkin
***************************************************** }
function fAnsiPos(const Substr, S: string; FromPos: integer): Integer; var P: PChar; begin Result := 0; P := AnsiStrPos(PChar(S) + fromPos - 1, PChar(SubStr)); if P <> nilthen Result := Integer(P) - Integer(PChar(S)) + 1; end;
|
- Подробности
- Родительская категория: Работа со строками
- Категория: Разбор строки, выделение элементов, поиск
Code: |
// Get the Position of a string, starting at the end // Ruckwartiges Vorkommen einer Zeichenkette innerhalb eines strings, Position von hinten
function LastPos(SearchStr, Str: string): Integer; var i: Integer; TempStr: string; begin Result := Pos(SearchStr, Str); if Result = 0then Exit; if (Length(Str) > 0) and (Length(SearchStr) > 0) then begin for i := Length(Str) + Length(SearchStr) - 1downto Result do begin TempStr := Copy(Str, i, Length(Str)); if Pos(SearchStr, TempStr) > 0then begin Result := i; break; end; end; end; end;
// Search for the next occurence of a string from a certain Position // Nachstes Vorkommen einer Zeichenkette ab einer frei definierbaren Stelle im string
function NextPos(SearchStr, Str: string; Position: Integer): Integer; begin Delete(Str, 1, Position - 1); Result := Pos(SearchStr, upperCase(Str)); if Result = 0then Exit; if (Length(Str) > 0) and (Length(SearchStr) > 0) then Result := Result + Position + 1; end;
// Get the number of characters from a certain Position to the string to be searched // Anzahl der Zeichen von einer definierbaren Position zur gesuchten Zeichenkette
function NextPosRel(SearchStr, Str: string; Position: Integer): Integer; begin Delete(Str, 1, Position - 1); Result := Pos(SearchStr, UpperCase(Str)) - 1; end;
// simple replacement for strings // einfaches Ersetzen von Zeichenketten
function ReplaceStr(Str, SearchStr, ReplaceStr: string): string; begin while Pos(SearchStr, Str) <> 0do begin Insert(ReplaceStr, Str, Pos(SearchStr, Str)); Delete(Str, Pos(SearchStr, Str), Length(SearchStr)); end; Result := Str; end; |
- Подробности
- Родительская категория: Работа со строками
- Категория: Разбор строки, выделение элементов, поиск
Вариант 1.
В Дельфи есть специальный класс для хранения массивов строк - TStringList - очень рекомендую. Вот как вашу строку превратить в TStringList:
Объявление переменной
Code: |
var t:TStringList;
begin t:=TStringList.create; //создаём класс t.text:=stringReplace('Ваша строка для разделения',' ',#13#10,[rfReplaceAll]);//мы заменяем все пробелы на символы конца строки //теперь можно убедится что у вас строка разбина на элементы: showmessage(t[0]); showmessage(t[1]); showmessage(t[2]); showmessage(t[3]); ... //после работы надо уничтожить класс t.free; |
Автор:Vit
Взято с Vingrad ruhttps://forum.vingrad
Вариант 2. Используем стандартные массивы:
Code: |
var a:arrayofstring;//наш массив s:string;//строка которую мы будем разбивать begin s:='Windows Messages SysUtils Variants Classes Graphics Controls Forms'; Repeat//мы постепенно заполняем массив на каждом шаге цикла по 1 элементу setlength(a,length(a)+1);//увеличиваем размер массива на 1 if pos(' ',s)>0then//если есть пробел то надо взять слово до пробела begin a[length(a)-1]:=copy(s,1, pos(' ',s));//присвоение последнему элементу массива первого слова s:=copy(s,pos(' ',s)+1, length(s));//удаляем из строки первое слово end else//в строке осталось только одно слово begin a[length(a)-1]:=s;// присвоим последнее слово break;//выход из цикла end; Until False;//цикл бесконечный, выход изнутри //теперь проверяем что получили showmessage(a[0]); showmessage(a[1]); showmessage(a[2]); |
После использования массива не забудте освободить память a:=nil или setlength(a,0)
Автор:Vit
Взято с Vingrad ruhttps://forum.vingrad
Code: |
procedure SplitOnWords(const s:string; Delimiters:setof char; Strings:TStrings); var p,sp:PChar; str:string;
begin include(Delimiters,#0); //чтоб уж наверняк p:=pointer(s); while true do begin //пропускаем все разделители в начале while p^ in Delimiters do if p^=#0then exit else inc(p); sp:=p; //пока не кончилось слово. whilenot (p^ in Delimiters) do inc(p);
//запоминаем слово SetLength(str,cardinal(p)-cardinal(sp)); Move(sp^,pointer(str)^,cardinal(p)-cardinal(sp)); Strings.Add(str); end; end; |
Автор:Fantasist
Взято с Vingrad ruhttps://forum.vingrad
См. также Парсинг строк
- Подробности
- Родительская категория: Работа со строками
- Категория: Разбор строки, выделение элементов, поиск
Code: |
unit splitfns; interface uses Classes, Sysutils; function GetNextToken(Const S: string; Separator: TSysCharSet; var StartPos: integer): String;
{Returns the next token (substring) from string S, starting at index StartPos and ending 1 character before the next occurrence of Separator (or at the end of S, whichever comes first).}
{StartPos returns the starting position for the next token, 1 more than the position in S of the end of this token}
procedure Split(const S: String; Separator: TSysCharSet; MyStringList: TStringList);
{Splits a string containing designated separators into tokens and adds them to MyStringList NOTE: MyStringList must be Created before being passed to this procedure and Freed after use}
function AddToken (const aToken, S: String; Separator: Char; StringLimit: integer): String;
{Used to join 2 strings with a separator character between them and can be used in a Join function} {The StringLimit parameter prevents the length of the Result String from exceeding a preset maximum}
implementation
function GetNextToken(Const S: string; Separator: TSysCharSet; var StartPos: integer): String; varIndex: integer; begin Result := ''; {Step over repeated separators} While (S[StartPos] in Separator) and (StartPos <= length(S)) do StartPos := StartPos + 1;
if StartPos > length(S) then Exit;
{Set Index to StartPos} Index := StartPos;
{Find the next Separator} Whilenot (S[Index] in Separator) and (Index <= length(S))doIndex := Index + 1;
{Copy the token to the Result} Result := Copy(S, StartPos, Index - StartPos);
{SetStartPos to next Character after the Separator} StartPos := Index + 1; end;
procedure Split(const S: String; Separator: TSysCharSet; MyStringList: TStringList); var Start: integer; begin Start := 1; While Start <= Length(S) do MyStringList.Add(GetNextToken(S, Separator, Start)); end;
function AddToken (const aToken, S: String; Separator: Char; StringLimit: integer): String; begin if Length(aToken) + Length(S) < StringLimit then begin {Add a separator unless the Result string is empty} if S = ''then Result := ''else Result := S + Separator;
{Add the token} Result := Result + aToken; end else {if the StringLimit would be exceeded, raise an exception} Raise Exception.Create('Cannot add token'); end; end.
|
пример использования:
Code: |
... data:= TStringList.Create; splited:=TStringList.Create; data.LoadFromFile(s); Split(data.Text,[',',' ',#10,#13,';','\"','.','!','-','+','*','/','\', '(',')','[',']','{','}','<','>','''','"','?','"','#',#0],splited); for i:= 0to splited.Count-1do begin ifnot words.Find(splited.Strings,adr) then words.Add(splited.Strings[i]); application.processmessages;[i]//make program to respond to user //commands while processing in case of very long string. end; ... |
Автор:Song
Взято из https://forum.sources
Некоторое время назад одна любезная душа прислала мне этот модуль. Я нашел его весьма полезным, но применять его вам надлежит с некоторой долей осторожности, ибо тэг %s иногда приводит к исключительным ситуациям.
Code: |
unit Scanf;
interface uses SysUtils;
type
EFormatError = class(ExCeption);
function Sscanf(const s: string; const fmt: string; const Pointers: arrayof Pointer): Integer; implementation
{ Sscanf выполняет синтаксический разбор входной строки. Параметры...
s - входная строка для разбора fmt - 'C' scanf-форматоподобная строка для управления разбором %d - преобразование в Long Integer %f - преобразование в Extended Float %s - преобразование в строку (ограничено пробелами) другой символ - приращение позиции s на "другой символ" пробел - ничего не делает Pointers - массив указателей на присваиваемые переменные
результат - количество действительно присвоенных переменных
Например, ... Sscanf('Name. Bill Time. 7:32.77 Age. 8', '. %s . %d:%f . %d', [@Name, @hrs, @min, @age]);
возвратит ... Name = Bill hrs = 7 min = 32.77 age = 8 }
function Sscanf(const s: string; const fmt: string;
const Pointers: arrayof Pointer): Integer; var
i, j, n, m: integer; s1: string; L: LongInt; X: Extended;
function GetInt: Integer; begin s1 := ''; while (s[n] = ' ') and (Length(s) > n) do inc(n); while (s[n] in ['0'..'9', '+', '-']) and (Length(s) >= n) do begin s1 := s1 + s[n]; inc(n); end; Result := Length(s1); end;
function GetFloat: Integer; begin s1 := ''; while (s[n] = ' ') and (Length(s) > n) do inc(n); while (s[n] in ['0'..'9', '+', '-', '.', 'e', 'E']) and (Length(s) >= n) do begin s1 := s1 + s[n]; inc(n); end; Result := Length(s1); end;
function GetString: Integer; begin s1 := ''; while (s[n] = ' ') and (Length(s) > n) do inc(n); while (s[n] <> ' ') and (Length(s) >= n) do begin s1 := s1 + s[n]; inc(n); end; Result := Length(s1); end;
function ScanStr(c: Char): Boolean; begin while (s[n] <> c) and (Length(s) > n) do inc(n); inc(n);
if (n <= Length(s)) then Result := True else Result := False; end;
function GetFmt: Integer; begin Result := -1;
while (TRUE) do begin while (fmt[m] = ' ') and (Length(fmt) > m) do inc(m); if (m >= Length(fmt)) then break;
if (fmt[m] = '%') then begin inc(m); case fmt[m] of 'd': Result := vtInteger; 'f': Result := vtExtended; 's': Result := vtString; end; inc(m); break; end;
if (ScanStr(fmt[m]) = False) then break; inc(m); end; end;
begin
n := 1; m := 1; Result := 0;
for i := 0to High(Pointers) do begin j := GetFmt;
case j of vtInteger: begin if GetInt > 0then begin L := StrToInt(s1); Move(L, Pointers[i]^, SizeOf(LongInt)); inc(Result); end else break; end;
vtExtended: begin if GetFloat > 0then begin X := StrToFloat(s1); Move(X, Pointers[i]^, SizeOf(Extended)); inc(Result); end else break; end;
vtString: begin if GetString > 0then begin Move(s1, Pointers[i]^, Length(s1) + 1); inc(Result); end else break; end;
else break; end; end; end;
end.
|
https://delphiworld.narod.
DelphiWorld 6.0
Code: |
// Parse a string, for example: // How do I get the "B" from "A|B|C|D|E|F"?
function Parse(Char, S: string; Count: Integer): string; var I: Integer; T: string; begin if S[Length(S)] <> Char then S := S + Char; for I := 1to Count do begin T := Copy(S, 0, Pos(Char, S) - 1); S := Copy(S, Pos(Char, S) + 1, Length(S)); end; Result := T; end;
procedure TForm1.Button1Click(Sender: TObject); begin ShowMessage(Parse('|', 'A|B|C|D|E|F', 2)); end;
{ Parameters:
Parse([Character, for example "|"], [The string], [The number, the "B" is the 2nd part of the string]);
This function is handy to use when sending data over the internet, for example a chat program: Name|Text. Note: Be sure there's no "Char" in the string! Use a unused character like "|" or "?". } |
Взято с сайта: https://www.swissdelphicenter
- Подробности
- Родительская категория: Работа со строками
- Категория: Разбор строки, выделение элементов, поиск
Code: |
function CountPos(const subtext: string; Text: string): Integer; begin if (Length(subtext) = 0) or (Length(Text) = 0) or (Pos(subtext, Text) = 0) then Result := 0 else Result := (Length(Text) - Length(StringReplace(Text, subtext, '', [rfReplaceAll]))) div Length(subtext); end; |
Code: |
{ **** UBPFD *********** by delphibase.endimus.com **** >> Подсчёт количества вхождений символа в строке
Функцийка считает количество повторений символа заданного InputSubStr в строке InputStr.
Зависимости: Стандартные модули Автор: Ru, Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра., Одесса (Украина) Copyright: DiVo 2003 creator Ru Дата: 18 ноября 2003 г. ***************************************************** }
function CntChRepet(InputStr: string; InputSubStr: char): integer; var i: integer; begin result := 0; for i := 1to length(InputStr) do if InputStr[i] = InputSubStr then inc(result); end; |
Code: |
{ **** UBPFD *********** by delphibase.endimus.com **** >> Подсчитать количество вхождений подстроки в строке
Понадобилось подсчитать количество вхождений подстроки в строку, вот и появилась эта функция. Возможно в ней и нет изюминки, но может кому и пригодится.
Зависимости: System Автор: Дмитрий, Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра., ICQ:155133146, Тольятти Copyright: Дмитрий Дата: 17 октября 2002 г. ***************************************************** }
function CntRecurrences(substr, str: string): integer; var cnt, p: integer; begin cnt := 0; while str <> ''do begin p := Pos(substr, str); if p > 0then inc(cnt) else p := 1; Delete(str, 1, (p + Length(substr) - 1)); end; Result := cnt; end; |
Автор: ___Nikolay
Code: |
// Кол-во вхождений символа в строку function SymbolEntersCount(s: string; ch: char): integer; var i: integer; begin Result := 0; if Trim(s) <> ''then for i := 1to Length(s) do if s[i] = ch then inc(Result); end;
|
- Подробности
- Родительская категория: Работа со строками
- Категория: Разбор строки, выделение элементов, поиск
Code: |
{ **** UBPFD *********** by delphibase.endimus **** >> Поиск N-ого вхождения подстроки в строку
Зависимости: SysUtils Автор: panov, panov @ hotbox.ru, Екатеринбург Copyright: panov
***************************************************** }
function SearchString(const FindStr, SourceString: string; Num: Integer): Integer; var FirstSym: PChar; //Ссылка на первый символ
function MyPos(const FindStr, SourceString: PChar; Num: Integer): PChar; begin Result := AnsiStrPos(SourceString, FindStr); //Поиск вхождения подстроки в строку if (Result = nil) then Exit; //Подстрока не найдена Inc(Result); //Смещаем указатель на следующий символ if Num = 1then Exit; //Если нужно первое вхождение - заканчиваем if num > 1then Result := MyPos(FindStr, Result, num - 1); //Рекурсивный поиск следующего вхождения end;
begin FirstSym := PChar(SourceString); //Присваиваем адрес первого символа исходной строки Result := MyPos(PChar(FindStr), PChar(SourceString), Num) - FirstSym; //Номер позиции в строке if Result < 0then Result := 0; //Возвращаем номер позиции end; //Пример использования:
var StrF, StrSrc: string; n: Integer; begin ... StrF := 'стр'; StrSrc := 'Поиск подстроки в строке'; n := SearchString(StrF, StrSrc, 2); //n будет равна 19 end; |
- Подробности
- Родительская категория: Работа со строками
- Категория: Разбор строки, выделение элементов, поиск
Страница 1 из 2