StrPos (RegEx) gives you the start character - how do you get the last character?

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: