Clear Create Cursor Test (testString m, replacement m) Insert Into Test (testString) Values ; ("Datum proizvod<PR>nje: <#nnnn PR#> aaa <#trt pr#> <<DATUMPROIZVODNJE>>") Insert Into Test (testString) Values ; ("Datum proizvod<PR>nje: <#nnnn PR aaa <<trt pr <<DATUMPROIZVODNJE>>") Insert Into Test (testString) Values ; ("Datum proizvod<PR>nje: <#nnnn PR#> aaa trt pr#> <<DATUMPROIZVODNJE>>") Insert Into Test (testString) Values ; ("Da<#tum proizvod<PR>nje: <#nnnn PR#> aaa <#trt pr#> <<DATUMPROIZVODNJE>>#>") Insert Into Test (testString) Values ; ("Da<#tum proizvod<PR>nje: <#nnnn PR#> aaa <#trt pr#> #> <# <<DATUMPROIZVODNJE>>#>More.") Insert Into Test (testString) Values ; ("<<Datum proizvod<PR>nje: <#nnnn PR#> aaa <#trt pr#> <<DATUMPROIZVODNJE>>>>") m.ReplaceFrom = "pr" m.ReplaceTo = "7777" Update Test ; SET replacement = CustomReplace(testString, m.ReplaceFrom, m.ReplaceTo) SET MEMOWIDTH TO 1024 Scan ? testString ? replacement ? '-----------------------------------------------------------' Endscan Procedure CustomReplace(tcSource, tcReplaceFrom, tcReplaceTo) Local lcCursor, lcTemp, lcResult, lnSelect lnSelect = Select(0) lcTemp = Sys(2015) lcResult = '' lcCursor = GetParts(m.tcSource) Select Cast(Iif( ; (Left(TagPart,2) = '<<' And Right(TagPart,2) = '>>') Or ; (Left(TagPart,2) = '<#' And Right(TagPart,2) = '#>'), ; TagPart, ; STRTRAN(TagPart, m.ReplaceFrom, m.ReplaceTo, 1, -1, 1+2)) As m) As TagPart ; FROM (m.lcCursor) ; into Cursor (m.lcTemp) ; nofilter Select (m.lcTemp) Scan lcResult = m.lcResult + TagPart Endscan Use In (Select (m.lcCursor)) Use In (Select (m.lcTemp)) Select (m.lnSelect) Return m.lcResult Endproc Procedure GetParts(tcSource) Local lnNext1, lnNext2, lnNext, lcLeft, lcRight, lcSegment, lcCursor lcCursor = Sys(2015) Create Cursor (m.lcCursor) (TagPart m) Do While !Empty(m.tcSource) lnNext1 = Atc('<#', m.tcSource) lnNext2 = Atc('<<', m.tcSource) If m.lnNext1 = 0 And m.lnNext2 = 0 Insert Into (m.lcCursor) (TagPart) Values (m.tcSource) tcSource = '' Else If m.lnNext1 < m.lnNext2 lnNext = Iif(m.lnNext1 = 0, m.lnNext2, m.lnNext1) lcLeft = Iif(m.lnNext1 = 0, '<<', '<#') lcRight = Iif(m.lnNext1 = 0, '>>', '#>') Else lnNext = Iif(m.lnNext2 = 0, m.lnNext1, m.lnNext2) lcLeft = Iif(m.lnNext2 = 0, '<#', '<<') lcRight = Iif(m.lnNext2 = 0, '#>', '>>') Endif lcSegment = GetSegment(Substr(m.tcSource, m.lnNext), m.lcLeft, m.lcRight) If Len(m.lcSegment) = 0 Insert Into (m.lcCursor) (TagPart) Values (Left(m.tcSource, m.lnNext+1)) tcSource = Substr(m.tcSource, m.lnNext+2) Else Insert Into (m.lcCursor) (TagPart) Values (Left(m.tcSource, m.lnNext-1)) Insert Into (m.lcCursor) (TagPart) Values (m.lcSegment) tcSource = Substr(m.tcSource, m.lnNext + Len(m.lcSegment)) Endif Endif Enddo Return m.lcCursor Endproc * Get the segment that starts with m.tcLeft * String already starts with m.tcLeft Procedure GetSegment(tcString, tcLeft, tcRight) Local lnLeft, lnRight, lnOccurence, llDone, lcSegment lcSegment = '' lnOccurence = 1 Do While !m.llDone lnRight = Atc(m.tcRight, m.tcString, m.lnOccurence) lnLeft = Atc(m.tcLeft, m.tcString, m.lnOccurence+1) Do Case Case m.lnRight = 0 m.llDone = .T. Case m.lnLeft = 0 Or (m.lnLeft > m.lnRight) m.llDone = .T. lcSegment = Left(m.tcString, m.lnRight+Len(m.tcRight)-1) Otherwise m.lnOccurence = m.lnOccurence + 1 Endcase Enddo Return m.lcSegment Endproc