I need to replace the string matching a regex with another string. The new string is created by a function, which I only want to call it if there is a match. This is my current code, I wonder if there is a simpler or more efficient way to do the replace:
st.FindMatchPosition(regex,starts,ends,Match:Regular,TRUE)
IF starts AND ends
st.SetValue( st.Slice(1,starts-1) & createnewvalue() & st.Slice(ends+1) )
END
@vitesse@Bruce Would it be too much work to add methods .ReplaceMatch(...) and .ReplacePosition(...)? If there isnât something similar already that I missed. Thanks in advance for your comments.
Before my system and backups got wiped a few weeks ago I had code that did this and it worked in the templates as well.
I seem to remember posting some code on here which would help you get the start and finish positions using strpos. I think its written in clarion but it might also be a template language code example.
well thatâs a coincidence - I wrote code to do this over the weekend and just yesterday sent it to Bruce for consideration for inclusion in a future version of ST along with a bunch of other stuff.
I called the new method ReplaceSlice and the comment in the code says:
!----------------------------------------------------------------------------------
! Sets the value of the specified region within the string to the passed string.
! Unlike setSlice() which either truncates or space fills the new value to fit the
! existing size of the slice, replaceSlice() will expand or contract the slice
! within the value string to exactly fit the newValue.
and would be more efficient as it is not doing a âdummy searchâ before the replace.
as regards your current code
st.FindMatchPosition(regex,starts,ends,Match:Regular,TRUE)
IF starts AND ends
st.SetValue( st.Slice(1,starts-1) & createnewvalue() & st.Slice(ends+1) )
END
I suggest changing the test so instead have
st.FindMatchPosition(regex,starts,ends,Match:Regular,TRUE)
IF starts AND ends >= starts
st.SetValue( st.Slice(1,starts-1) & createnewvalue() & st.Slice(ends+1) )
END
or use the replace code with a dummy search which might be a little faster:
IF starts AND ends >= starts
st.replace(st.slice(starts,ends),createnewvalue(),1,starts)
END
then if/when replaceSlice becomes available, instead use:
IF starts AND ends >= starts
st.replaceSlice(starts,ends,createnewvalue())
END
if you are keen to try replaceSlice now then (if Bruce is agreeable) I could send you my current version by PM.
one thing to note is that your st.FindMatchPosition will find the SMALLEST minimal match.
hopefully that is what you are after (and not the maximal âleftmost longestâ match).
if you are after that âleftmost longestâ match, have a look at the code here which includes StrPosAndLen which returns position and minimum and maximum length of string matched against regex There are a lot of âgotchasâ with strPos and this works around them.
I think this may be related to the StrPosAndLen code I mentioned in my previous message - I recall we had several conversations about this over a couple of years and it went through a few iterations before that version.
I had started mirroring the extra regex functionality microsoft provides in dotnet regex so theres no reason why capesoft or softvelocity cant mirror the dotnet regex functionality either.
Nice, thank you! I didnât know valuePtr was available and public. Itâs actually documented in the Upgrading section, so the âpuristsâ should be happy .