Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Replace inside memo field
Message
From
10/04/2019 19:51:31
Cetin Basoz
Engineerica Inc.
Izmir, Turkey
 
 
To
07/04/2019 10:24:12
General information
Forum:
Visual FoxPro
Category:
Coding, syntax & commands
Miscellaneous
Thread ID:
01667999
Message ID:
01668042
Views:
124
Likes (1)
As in your previous Textmerge thread, I think you are not doing something good. I explained the reasons there, this one is worse :(
Probably all your cases would be like in the sample you gave without no nesting and no unmatched pairs of delimiters. Then Antonio's code would work perfectly well. If side cases might there be then things get complex and you might need to redefine your rules:
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
Çetin Basöz

The way to Go
Flutter - For mobile, web and desktop.
World's most advanced open source relational database.
.Net for foxheads - Blog (main)
FoxSharp - Blog (mirror)
Welcome to FoxyClasses

LinqPad - C#,VB,F#,SQL,eSQL ... scratchpad
Previous
Reply
Map
View

Click here to load this message in the networking platform