Page 1 of 1

Scintilla regex search with groups

Posted: Sat Sep 06, 2014 12:11 pm
by eddy

Code: Select all

CompilerIf #PB_Compiler_Unicode
  #TextEncoding = #PB_UTF8
CompilerElse 
  #TextEncoding = #PB_Ascii
CompilerEndIf

Procedure MakeScintillaText(text.s, *sciLength.Integer=0) 
  Static sciLength : sciLength=StringByteLength(text, #TextEncoding)
  Static sciText.s : sciText = Space(sciLength)
  If *sciLength : *sciLength\i=sciLength : EndIf ;<--- return scintilla buffer length (required for certain scintilla command) 
  PokeS(@sciText, text, -1, #TextEncoding)
  ProcedureReturn @sciText
EndProcedure

Procedure.s ScintillaRegexGroup(Scintilla, group, maxLength=1024)
  If group>0
    Static *sciText : *sciText=AllocateMemory(maxLength)    
    If *sciText
      Protected sciLength=ScintillaSendMessage(Scintilla,#SCI_GETTAG,group,*sciText)                   
      If sciLength>0
        ProcedureReturn PeekS(*sciText, sciLength, #TextEncoding)
      EndIf     
    EndIf
  EndIf   
EndProcedure

CompilerIf #PB_Compiler_IsMainFile
  ; ********************
  ; EXAMPLE 
  ; ********************
  
  CompilerIf Not #PB_Compiler_Unicode
    MessageRequester("Warning","This program must be compiled with UNICODE compiler option!")
    End 
  CompilerEndIf   
  
  If OpenWindow(0, 0, 0, 450, 200, "Scintilla REGEX Search with backreferences", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    If InitScintilla()
      ScintillaGadget(0, 10, 10, 430, 180, 0)
      
      ; Init scintillla style and content
      ScintillaSendMessage(0, #SCI_SETCODEPAGE,#SC_CP_UTF8)
      ScintillaSendMessage(0, #SCI_STYLESETSIZE,0,14)
      ScintillaSendMessage(0, #SCI_STYLESETFONT,0,MakeScintillaText("Arial"))
      ScintillaSendMessage(0, #SCI_STYLESETFORE, 0, RGB(255, 0, 0))    
      ScintillaSendMessage(0, #SCI_SETTEXT, 0, MakeScintillaText("Hello ♥world♥...."))
      
      ; Set Search mode (REGEX + POSIX braces)
      ScintillaSendMessage(0, #SCI_SETSEARCHFLAGS,#SCFIND_REGEXP|#SCFIND_POSIX)
      
      ; Set search target range
      txtLen=ScintillaSendMessage(0,#SCI_GETTEXTLENGTH)
      ScintillaSendMessage(0, #SCI_SETTARGETSTART,0)
      ScintillaSendMessage(0, #SCI_SETTARGETEND,txtLen)
      
      ; Search
      regex=MakeScintillaText("(♥)(.+)\1",@regexLength)
      ;regex=MakeScintillaText("(\W)(.+)\1",@regexLength)
      firstMatchPos=ScintillaSendMessage(0, #SCI_SEARCHINTARGET,regexLength,regex)
      If firstMatchPos>-1
        firstMatchStartPos=ScintillaSendMessage(0, #SCI_GETTARGETSTART)
        firstMatchEndPos=ScintillaSendMessage(0, #SCI_GETTARGETEND)      
        ScintillaSendMessage(0,#SCI_SETSEL,firstMatchStartPos,firstMatchEndPos)
        
        Debug ScintillaRegexGroup(0,1) ; => ♥
        Debug ScintillaRegexGroup(0,2) ; => world
      EndIf     
      
    EndIf
    
    Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
  EndIf
  
CompilerEndIf