Issue with {n} Quantifiers in Clarion’s MATCH Function

Hi Mark and Carl

over on the newsgroups back in March last year, Alberto asked about this and I knocked up a function for him to expand the regex so it worked in Clarion. I released it under the MIT license so it is unencumbered.

ho ho ho - here’s a Christmas present and no need for any Clarion tax!

hth and Merry Christmas!

Geoff R

prototype is:
 
ExpandRegEx       PROCEDURE(string pRegex),string

and the code is:

ExpandRegEx       PROCEDURE (string pRegex)
!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
!
! ExpandRegEx - expand repetitions 
! eg. [0-9]{1,3} expands to [0-9][0-9]?[0-9]?
!     [0-9]{0,4} expands to [0-9]?[0-9]?[0-9]?[0-9]?
!
! Version 1.0 written on 15th March 2023 by Geoff Robinson vitesse AT gmail DOT com 
!
! MIT License
!
! Copyright (c) 2023 Geoffrey C. Robinson
!
! Permission is hereby granted, free of charge, to any person obtaining a copy
! of this software and associated documentation files (the "Software"), to deal
! in the Software without restriction, including without limitation the rights
! to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
! copies of the Software, and to permit persons to whom the Software is
! furnished to do so, subject to the following conditions:
!
! The above copyright notice and this permission notice shall be included in all
! copies or substantial portions of the Software.
!
! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
! IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
! FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
! AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
! LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
! OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
! SOFTWARE.
!
!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

st        StringTheory
ln        StringTheory     ! line
stTmp     StringTheory     ! temp worker

c         string(1),auto   ! char
b         byte, over(c)  

x         long,auto
y         long,auto

prevLen   long
prevLen2  long

minRepeat long,auto
maxRepeat long,auto

  code
  st.setValue(pRegex,st:clip)
  loop x = 1 to st._dataEnd
    c = st.valuePtr[x]
    case b
    of val('[')
      y = st.matchBrackets('[',']',x)
      if y = x + 1 ! allow for where ] is included char
        y = st.findChar(']',y+1)
      end
    of val('{{')
      y = st.matchBrackets('{{','}',x)
    else
      y = 0
    end
    if y
      st.addLine(st:end,st.valuePtr[x : y])
      x = y 
    else
      st.addLine(st:end,c)
    end
  end 

  st.free()  
  loop x = 1 to st.records()
    prevLen2 = prevLen
    prevLen  = st._dataEnd
    ln.setValue(st.getLine(x))
    st.append(ln)
?   assert(ln._dataEnd > 0)
    if ln._dataEnd = 1        or |
       ln.valuePtr[1] <> '{{' or |
       ln.valuePtr[ln._dataEnd] <> '}'
      cycle
    end
    stTmp.setValue(ln)
    stTmp.crop(2, stTmp._dataEnd - 1) ! strip { and }
    stTmp.split(',')
    if stTmp.records() <> 2 then cycle.

    stTmp.setValue(stTmp.getLine(1))
    stTmp.trim()
    if not stTmp.isAllDigits() then cycle.
    minRepeat = stTmp.getValue()

    stTmp.setValue(stTmp.getLine(2))
    stTmp.trim()
    if not stTmp.isAllDigits() then cycle.
    maxRepeat = stTmp.getValue()

    if minRepeat > maxRepeat then cycle.

    st.setLength(prevLen)  ! remove repeat group eg. {1,4}
    stTmp.setValue(st.slice(prevLen2+1)) ! tok to be repeated
    st.setLength(prevLen2) ! remove tok to be repeated

    loop y = 1 to maxRepeat
      st.append(stTmp)
      if y > minRepeat then st.append('?'). ! optional?
    end
  end 

  if st._dataEnd < 1
    return ''
  else
    return st.valuePtr[1 : st._dataEnd]
  end

EDIT 1: I see Alberto’s requirement/request was for {min,max} and so this is probably only part of the solution as it probably doesn’t cater for exact number such as {5}. I guess you could use {5,5} but that is not ideal. (Sorry I don’t have time to look further right now as got to get the house organised for extended family coming for Christmas!)