Hi Richard
I was just working on a solution based on another thread where you were having problems with strpos clipping spaces and I also am searching for unused characters starting at chr(255) and working down.
I have written a new function “StrPosAndLen” which returns the starting position as does strpos() but also has two parameters where it returns the minimum and maximum lengths.
It finds a replacement character for space (if possible) as you have mentioned.
Usually I use StringTheory for anything like this but I seem to recall you are not using ST so I have done it the old long-hand way, which means this is a bit longer than it needs to be.
Anyway this is probably a “work in progress” but it passes my limited testing -can you please test it in your environment and let me know if it works for you. If it doesn’t work in your tests can you please provide the failing tests for me to check.
Hope this helps & cheers
Geoff R
StrPosAndLen PROCEDURE (string pText,string pRegex,*long pMinLen,*long pMaxLen)
! (c) 2024 Geoff Robinson Vitessegr at gmail dot com
! 29 October 2024
! released under the MIT License https://opensource.org/license/mit
!
! 1 November 2024 - move check to get start position to be AFTER space substitution
! - note: this code does not cope with ranges when replacing spaces!!
x long,auto
max long,auto
b byte
c string(1),over(b) ! single char over b
stPos long ! start position (return value)
dollarEnded string(size(pRegex)+1)
regex &string
CODE
pMinLen = 0; pMaxLen = 0 ! initialise/clear
if size(pText) = 0 or size(pRegex) = 0 then return 0.
if instring(' ',pText) or instring(' ',pRegex) ! includes space so need to replace spaces if possible
loop b = 255 to 1 by -1
if instring(c,pText) then cycle.
if instring(c,pRegex) then cycle.
if instring(c,'^$.[]|{{}*+?\-') then cycle. ! avoid special regex chars
break
end
end
if b ! if we have a replacement char for space then do replacements
loop x = 1 to size(pText)
if pText[x] = ' ' then pText[x] = c.
end
loop x = 1 to size(pRegex)
if pRegex[x] = ' ' then pRegex[x] = c.
end
end
stPos = strPos(pText, pRegex) ! get start position
if ~stPos then return 0. ! no match
if stPos = size(pText) ! single char match
pMinLen = 1
pMaxLen = 1
return stPos
end
if pRegex[size(pRegex)] = '$' and sub(pRegex,size(pRegex)-1,1) <> '\'
regex &= pRegex
else
dollarEnded = pRegex & '$'
regex &= dollarEnded
end
max = size(pText) - stPos ! max increment size
loop x = 0 to max
if strPos(pText[stPos : stPos+x],regex)
pMaxLen = x + 1
if pMinLen = 0 then pMinLen = pMaxLen.
elsif pMaxLen
break
end
end
return stPos ! return starting position
!----
#Edit1 added '-' in regex chars to avoid "if instring(c,'^$.[]|{{}*+?\-') then cycle."
#Edit2 moved check to get start position to be AFTER space substitution
#Edit3 needed to move code to append $ to regex to be AFTER check start pos
#Edit4 (7th November 2024) I’ve just posted a much better solution to this problem (fixing issues with trailing spaces WITHOUT trying to find a substitution character) at: