Author Topic: Search and replace multiple regex in REALbasic  (Read 2375 times)

Offline OS923

  • Platinum Member
  • *****
  • Posts: 888
Search and replace multiple regex in REALbasic
« on: August 27, 2020, 01:48:35 PM »
I found a simple solution for searching and replacing multiple regular expressions in REALbasic.
Suppose that you want to search and replace 3 expressions r1, r2 and r3.
Search first for (r1)|(r2)|(r3).
If you find a match M, then search each expression in M and check whether the match is equal to M.
This showed to be reasonably fast.

Code: [Select]
MultiRegEx.Append:
Function Append(search as string,replace as string) As boolean
  dim r as RegEx
  dim s as string
 
  r=new RegEx
  if r=nil then
    MsgBox("Out of memory.")
    return false
  end
 
  r.searchPattern=search
  r.replacementPattern=replace
  r.options.matchEmpty=false
 
  m_reT.Append(r)
 
  s="("+search+")"
  m_searchT.Append(s)
 
  return true
End Function

MultiRegEx.Merge:
Function Merge() As boolean
  dim r as RegEx
  dim search as string
 
  r=new RegEx
  if r=nil then
    MsgBox("Out of memory.")
    return false
  end
 
  search=Join(m_searchT,"|")
  r.searchPattern=search
  r.options.matchEmpty=false
 
  m_re=r
 
  return true
End Function

MultiRegEx.ReplaceAll:
Function ReplaceAll(before as string,byref after as string) As boolean
  dim before_len as integer
  dim start as integer
  dim skip_len as integer
  dim skip_text as string
  dim partT() as string
  dim replace_text as string
 
  dim found as boolean
 
  dim multi_pos as integer
  dim multi_match as string
  dim multi_len as integer
 
  dim pos as integer
  dim match as string
  dim len as integer
 
  // Rem: !!! Indexes are 0-counted for regexes, but 1-counted for strings !!!
 
  start=0
  before_len=before.Len()
  while start<before_len
    if not SearchMulti(before,start,found,multi_pos,multi_match) then
      MsgBox("Multi search fails.")
      return false
    end
   
    if not found then
      skip_len=before_len-start
      skip_text=before.Mid(start+1,skip_len) // Rem: !!! +1.
      partT.Append(skip_text)
      start=before_len
    else
      if multi_pos>start then
        skip_len=multi_pos-start
        skip_text=before.Mid(start+1,skip_len) // Rem: !!! +1.
        partT.Append(skip_text)
      end
     
      if not ReplaceTable(multi_match,replace_text) then
        MsgBox("Table replace fails.")
        return false
      end
      partT.Append(replace_text)
     
      multi_len=multi_match.Len()
      start=multi_pos+multi_len
    end
  wend
 
  after=Join(partT,"")
 
  return true
End Function

MultiRegEx.SearchMulti:
Private Function SearchMulti(s as string,start as integer,byref found as boolean,byref pos as integer,byref match as string) As boolean
  dim m as RegExMatch
  dim message as string
 
  m=m_re.Search(s,start)
  if m=nil then
    found=false
    return true
  end
  found=true
  pos=m.subExpressionStartB(0)
  match=m.subExpressionString(0)
  return true
exception err as RegExException
  message="Error: "+err.message+EndOfLine.Macintosh _
      +"Search pattern: "+m_re.searchPattern+EndOfLine.Macintosh
  MsgBox(message)
  return false
End Function

MultiRegEx.ReplaceTable:
Private Function ReplaceTable(before as string,byref after as string) As boolean
  dim before_len as integer
  dim r as RegEx
  dim m as RegExMatch
 
  dim match as string
  dim len as integer
 
  dim message as string
 
  before_len=before.Len()
  for each r in m_reT
    m=r.Search(before)
    if m<>nil then
      match=m.subExpressionString(0)
      len=match.Len()
      if len=before_len then
        after=r.Replace(before)
        return true
      end
    end
  next
  MsgBox("A matching expression wasn't found in the table.")
  return true
exception err as RegExException
  message="Error: "+err.message+EndOfLine.Macintosh _
      +"Search pattern: "+r.searchPattern+EndOfLine.Macintosh
  MsgBox(message)
  return false
End Function

Offline OS923

  • Platinum Member
  • *****
  • Posts: 888
Re: Search and replace multiple regex in REALbasic
« Reply #1 on: September 07, 2020, 09:27:02 AM »
The last return true has to be return false.
If you want to use ^ $ \b and \B then you have to extend the match with 2 characters and start your replace at position 2. I do this in my Realace all program and this works well.