Odd issue with some string manipulation, any ideas?

New to FreeBASIC? Post your questions here.
Post Reply
olympic sleeper
Posts: 41
Joined: Jun 07, 2020 15:47

Odd issue with some string manipulation, any ideas?

Post by olympic sleeper »

Hello,

I have a string in the form

Code: Select all

result="(2)(3)(4)(14)(15)(16)(30)(62)<57>(64)(65)<71><72><66>(67)(68)(70)<69>(57I1O2)<58><60><63>(71)(72)(66)(69)<48>(58)<59>(60)<61>(63)(48)(59)(61)"
and a bit of code

Code: Select all

	cont_tag="<"+to_string(obj_id)+">"
	
	if instr(result,cont_tag)>0 then result=left(result,instr(result,cont_tag))+mid(result,instr(result,cont_tag)+len(cont_tag)+1)
	
	cont_tag="("+to_string(obj_id)+")"
	if instr(result,cont_tag)>0 then result=left(result,instr(result,cont_tag)-1)+mid(result,instr(result,cont_tag)+len(cont_tag))
	
	print result
to_string is a function that takes the str(number) and strips any leading space.

The two result= parts after the ifs look for (number) and <number> in result and strip them out. Eg if number is 58 the result will be

Code: Select all

(2)(3)(4)(14)(15)(16)(30)(62)<57>(64)(65)<71><72><66>(67)(68)(70)<69>(57I1O2)<60><63>(71)(72)(66)(69)<48><59>(60)<61>(63)(48)(59)(61)
However I have to have two very slightly different lines with +1 in slightly different places, otherwise they do not work and I have no idea why, the only difference in the search as one is <58> and the other (58) -or any other number.

Anyone know?
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Odd issue with some string manipulation, any ideas?

Post by fxm »

The right expression is in both cases:
result=left(result,instr(result,cont_tag)-1)+mid(result,instr(result,cont_tag)+len(cont_tag))

Note:
result=left(result,instr(result,cont_tag))+mid(result,instr(result,cont_tag)+len(cont_tag)+1) works for "<58>" only because the next number has the same delimiters if although a +1 shift in the deletion process does not matter, which is not the case with "(58)".
olympic sleeper
Posts: 41
Joined: Jun 07, 2020 15:47

Re: Odd issue with some string manipulation, any ideas?

Post by olympic sleeper »

Many thanks fxm, I'm struggling right now with working through the logic of several lines like this. I know what I want, but teasing them out is proving a bit frustrating.

Could you perhaps help with working out another? In this string again;

Code: Select all

result="(2)(3)(4)(14)(15)(16)(30)(62)<57>(64)(65)<71><72><66>(67)(68)(70)<69>(57I1O2)<58><60><63>(71)(72)(66)(69)<48>(58)<59>(60)<61>(63)(48)(59)(61)"
I need to take everything before a (number) and everything after the last <x> before (another number), not a good explanation so taking 58 as an example. There is a (58) near the end - the string goes ...<48>(58)<59>(60)... . I want everything before that (58) and everything after, but not including, the <59>, so the result would be...<48>(60) - the (58)<59> part has been removed. The code to do the 1st is that previous left statement

Code: Select all

left(result,instr(result,cont_tag))
but I am completely stumped as to how to get the part after the <59> - I know that I have to put an instr in a mid like - mid(result,instr<something>) but that instr has me at a loss. So far I have

Code: Select all

mid(result,instr(result,cont_tag)+len(cont_tag))
but this is outputting <59>(60)<61>(63)(48)(59)(61).It would be easy of there was only ever one 2 digit <number> tag, but there are n and some are 3 digits.
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Odd issue with some string manipulation, any ideas?

Post by dodicat »

You need a search and replace function to do the work for you.
Note also the keyword trim, by default it removes spaces at both ends of a string.

Code: Select all


var result="(2)(3)(4)(14)(15)(16)(30)(62)<57>(64)(65)<71><72><66>(67)(68)(70)<69>(57I1O2)<58><60><63>(71)(72)(66)(69)<48>(58)<59>(60)<61>(63)(48)(59)(61)"

Function SAR(stringin As String,find As String,replace As String) As String 
    Dim s As String=stringin
    Dim As Long position=Instr(s,find)
    While position>0
        s=Mid(s,1,position-1) & replace & Mid(s,position+Len(find))
        position=Instr(position+Len(replace),s,find)
    Wend
    Return s
End Function



print "original"
print result
print
Var answer=SAR(result,"(58)","")
print "intermediate result"
Print answer
print
print "final result"
answer= SAR(answer,"<59>","")
print answer

sleep
 
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Odd issue with some string manipulation, any ideas?

Post by fxm »

olympic sleeper wrote:I need to take everything before a (number) and everything after the last <x> before (another number), not a good explanation so taking 58 as an example. There is a (58) near the end - the string goes ...<48>(58)<59>(60)... . I want everything before that (58) and everything after, but not including, the <59>, so the result would be...<48>(60) - the (58)<59> part has been removed. The code to do the 1st is that previous left statement
Still not clear this requirement !
grindstone
Posts: 862
Joined: May 05, 2015 5:35
Location: Germany

Re: Odd issue with some string manipulation, any ideas?

Post by grindstone »

Using pointers considerably helps to keep track of string positions:

Code: Select all

Dim As String result, newstring, first, last
Dim As Integer b, e 'pointers to "begin" and "end"

result = "(2)(3)(4)(14)(15)(16)(30)(62)<57>(64)(65)<71><72><66>(67)(68)(70)<69>(57I1O2)<58><60><63>(71)(72)(66)(69)<48>(58)<59>(60)<61>(63)(48)(59)(61)"
first = "(58)"
last = "<59>"

b = InStr(result, first) - 1 'seek the position of the "(58)" and subtract 1. b now points to the position before the "(58)"
e = InStr(b, result, last) + Len(first) 'seek the position of the "<59>", beginning at the position of the "(58)", and add the length of the "<59>". e now points the the position after the "<59>"

newstring = Left(result, b) + Mid(result, e) 'build the new string

Print newstring
Sleep
olympic sleeper
Posts: 41
Joined: Jun 07, 2020 15:47

Re: Odd issue with some string manipulation, any ideas?

Post by olympic sleeper »

Hello and many thanks for the help. I've finally got my brain around the nessesary line, its:

Code: Select all

=mid(result,instr(result,cont_tag)+len(cont_tag)+instr(mid(result,instr(result,cont_tag)+len(cont_tag)),"(")-1)
Which is just horrible but, I think, works. I needed to be able to discard anything between a known (something) and an unknown (x), without knowing what was between the two or how much there was. Sorry my explanation of the problem was not very clear, and I suspect this one won't be much better.

Up to this point the code knows the (something) eg (58) but has no clue on anything else, other than the fact there *may* be something after that which *may* be in the form of <x><y><z> where x,y,z are numbers eg <10><52><11>. However there could be none in which case the string could be (58)(61), or they may be n <number> combinations between the known (number) and the unknown. Just to add to the confusion the known (number) could be at the end of the string so I had to account for that as well.

In the above result is the string I am mangling, and cont_tag is the known (number), eg (58), the "(" near the end is looking for the start of another (number).

Thanks again.
badidea
Posts: 2591
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Odd issue with some string manipulation, any ideas?

Post by badidea »

olympic sleeper wrote:

Code: Select all

=mid(result,instr(result,cont_tag)+len(cont_tag)+instr(mid(result,instr(result,cont_tag)+len(cont_tag)),"(")-1)
Do you still understand that line of code tomorrow or next year?
Intermediate variables can help:

Code: Select all

dim as string result = "(2)(3)(4)(14)(15)(16)(30)(62)<57>(64)(65)<71><72><66>(67)(68)(70)<69>(57I1O2)<58><60><63>(71)(72)(66)(69)<48>(58)<59>(60)<61>(63)(48)(59)(61)"
print "Input: " & result

dim as integer obj_id = 58
dim as string cont_tag = "<" + str(obj_id) + ">"
print "Tag: " & cont_tag

dim as integer start = instr(result, cont_tag)
dim as integer length = len(cont_tag)
dim as integer skip = instr(mid(result, start + length), "(")

print "Output: " & mid(result, start + length + skip - 1)
olympic sleeper
Posts: 41
Joined: Jun 07, 2020 15:47

Re: Odd issue with some string manipulation, any ideas?

Post by olympic sleeper »

Many thanks for the reply and code segment.

To be honest I don't fully understand that line now, so in a year probably not. Most of my code uses intermediate steps, but for some reason I just could not work out how to do so here - which resulted in that hideous pseudo Perl expression.

I also did not know you could assign vars values using expressions in dims, just thought that they had to be constants so many thanks for showing this.
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: Odd issue with some string manipulation, any ideas?

Post by counting_pine »

Code: Select all

dim as integer skip = instr(mid(result, start + length), "(")

print "Output: " & mid(result, start + length + skip - 1)
It's worth knowing that Instr() can take an additional parameter to give the start position for the search. This is simpler than using Instr(mid(...)), and is more efficient since Mid() will have to make a temporary copy of the whole substring.

So you should be able to optimise this to:

Code: Select all

dim as integer skip = instr(start + length, "(")

print "Output: " & mid(result, skip - 1)
olympic sleeper
Posts: 41
Joined: Jun 07, 2020 15:47

Re: Odd issue with some string manipulation, any ideas?

Post by olympic sleeper »

Many thanks, another of the (many) things that have slipped passed me.
Post Reply