Yes this is very true!
I did some tests and you are quite right about the spaces on the end. I am not sure if that is deliberate or is a bug in strPos.
ans1 = strPosLen('#ENDAT','#[A-Za-z]+')
if ans1 <> 6 then stop('strPosLen test 1 failed : expected 6 but got ' & ans1).
ans1 = strPosLen('#ENDAT','#[A-Za-z]')
if ans1 <> 2 then stop('strPosLen test 2 failed : expected 2 but got ' & ans1).
ans1 = strPosLen('what#ever123','#[A-Za-z]+')
if ans1 <> 5 then stop('strPosLen test 3 failed : expected 5 but got ' & ans1).
ans1 = strPosLen('#ENDAT ','#[A-Za-z]+')
if ans1 <> 6 then stop('strPosLen test 4 failed : expected 6 but got ' & ans1).
doing these tests my earlier version of strPosLen fails on test 4 which you can see has six spaces after #ENDAT. This test returned 12 rather than 6 as the trailing spaces were counted.
I cannot readily see of a universal way to avoid this as sometimes you might have regex’s where you want to include trailing spaces.
So for now I have added an extra optional parameter which defaults to stripping off trailing spaces. If you have a regex where you want the trailing spaces counted then you would add a third parameter of false:
ans1 = strPosLen('#ENDAT ','#[A-Za-z]+',false)
if ans1 <> 12 then stop('strPosLen test 5 failed : expected 12 but got ' & ans1).
The following code passes these five tests:
prototype :
StrPosLen Procedure(string pText, string pRegex, bool pExcludeTrailingSpaces=true),LONG !return the maximum matching string length
code:
StrPosLen PROCEDURE (string pText,string pRegex,bool pExcludeTrailingSpaces)
x long,auto
max long,auto
len long
stPos long
regex &string
CODE
!if ~address(pText) then return 0. ! uncomment this line if you decide to pass pText by reference instead of value
if size(ptext) = 0 or size(pRegex) = 0 then return 0.
stPos = strPos(pText, pRegex) ! get start position
if ~stPos then return 0. ! no match
if stPos = size(pText) then return 1. ! match on last char
if pRegex[size(pRegex)] = '$'
regex &= pRegex ! point at passed regex
else
regex &= new String(size(pRegex)+1)
regex = pRegex & '$'
end
max = size(pText) - stPos ! max increment size
loop x = 0 to max
if strPos(pText[stPos : stPos+x],regex)
len = x + 1
elsif len
break
end
end
if address(regex) <> address(pRegex) then dispose(regex).
if len and pExcludeTrailingSpaces
len = len(clip(pText[stPos : stPos+len-1]))
end
return len
hth
Geoff R
#Edit1 (30th October 2024) change “loop x = 1 to max” to “loop x = 0 to max”
#Edit2 (7th November 2024) I’ve just posted a much better solution to this problem (fixing issues with trailing spaces) at: