123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998 |
- ' Copyright (c) 2007-2024 Bruce A Henderson
- ' All rights reserved.
- '
- ' Redistribution and use in source and binary forms, with or without
- ' modification, are permitted provided that the following conditions are met:
- ' * Redistributions of source code must retain the above copyright
- ' notice, this list of conditions and the following disclaimer.
- ' * Redistributions in binary form must reproduce the above copyright
- ' notice, this list of conditions and the following disclaimer in the
- ' documentation and/or other materials provided with the distribution.
- ' * Neither the name of Bruce A Henderson nor the
- ' names of its contributors may be used to endorse or promote products
- ' derived from this software without specific prior written permission.
- '
- ' THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
- ' EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- ' WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- ' DISCLAIMED. IN NO EVENT SHALL Bruce A Henderson BE LIABLE FOR ANY
- ' DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- ' (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- ' LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- ' ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- ' (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- ' SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- '
- SuperStrict
- Rem
- bbdoc: Regular Expressions
- End Rem
- Module Text.RegEx
- ModuleInfo "Version: 1.12"
- ModuleInfo "Author: PCRE - Philip Hazel"
- ModuleInfo "License: BSD"
- ModuleInfo "Copyright: PCRE - 1997-2021 University of Cambridge"
- ModuleInfo "Copyright: Wrapper - 2007-2024 Bruce A Henderson"
- ModuleInfo "History: 1.12"
- ModuleInfo "History: Updated to PCRE 10.43"
- ModuleInfo "History: Options are now configured per search. Default options are used if none provided."
- ModuleInfo "History: Added SetDefaultOptions method."
- ModuleInfo "History: Options can be ignored in preference for pattern provided options."
- ModuleInfo "History: 1.11"
- ModuleInfo "History: Updated to PCRE 10.39"
- ModuleInfo "History: 1.10"
- ModuleInfo "History: Updated to PCRE 10.31"
- ModuleInfo "History: 1.09"
- ModuleInfo "History: Fixed issue using wrong ovector offset."
- ModuleInfo "History: 1.08"
- ModuleInfo "History: Updated to PCRE 10.30"
- ModuleInfo "History: 1.07"
- ModuleInfo "History: Updated for 64-bit."
- ModuleInfo "History: 1.06"
- ModuleInfo "History: Updated to PCRE 10.00"
- ModuleInfo "History: Changed TRegExMatch to get data as required, rather than cache it."
- ModuleInfo "History: Added support for JIT compilation via new options."
- ModuleInfo "History: Added ByName methods for sub expression retrieval."
- ModuleInfo "History: 1.05"
- ModuleInfo "History: Updated to PCRE 8.34"
- ModuleInfo "History: Changed to use pcre16 functions, which is BlitzMax's native character size. (no more utf8 conversions)"
- ModuleInfo "History: Don't include the zero-termination character in sub expressions."
- ModuleInfo "History: 1.04"
- ModuleInfo "History: Updated to PCRE 8.0"
- ModuleInfo "History: Fixed offset problems when working with non-ascii text."
- ModuleInfo "History: Fixed Replace() where loop was overflowing."
- ModuleInfo "History: Added test_08 for utf-8."
- ModuleInfo "History: 1.03"
- ModuleInfo "History: Updated to PCRE 7.4"
- ModuleInfo "History: 1.02"
- ModuleInfo "History: Added grable's subquery/replace tweak."
- ModuleInfo "History: 1.01"
- ModuleInfo "History: Options now global."
- ModuleInfo "History: 1.00"
- ModuleInfo "History: Initial Release. (PCRE 7.0)"
- ModuleInfo "CC_OPTS: -DHAVE_CONFIG_H -DPCRE2_CODE_UNIT_WIDTH=16"
- ?macos
- ModuleInfo "CC_VOPT: osversion|-mmacosx-version-min=11.00"
- ?
- Import "common.bmx"
- Rem
- bbdoc: Performs #Find and #Replace / #ReplaceAll on strings using Perl Compatible Regular Expressions.
- End Rem
- Type TRegEx
- ' Configures the way in which Regular Expressions are handled.
- Global defaultOptions:TRegExOptions
- ' The options to use for this search.
- Field options:TRegExOptions
- ' The pattern to search for.
- Field searchPattern:String
- ' The replacement pattern string.
- 'Field replacePattern:String
-
- Field lastPattern:String
- Field lastTarget:String
-
- ' pointer to the target string (as a WString)
- Field TArg:Byte Ptr
- ' the length of the target string
- Field targLength:Size_T
-
- Field lastEndPos:Size_T
-
- ' pointer to the compiled expression
- Field pcre:Byte Ptr
-
- ' pointer to the offsets vector, owned by pcre2
- Field offsets:Size_T Ptr
- ' number of offsets
- Field sizeOffsets:Int
-
- Field matchPtr:Byte Ptr
-
- Field compiled:Int = False
-
- Method Delete()
-
- If TArg Then
- MemFree(TArg)
- End If
-
- If matchPtr Then
- pcre2_match_data_free_16(matchPtr)
- End If
-
- If pcre
- MemFree(pcre)
- EndIf
-
- End Method
- Rem
- bbdoc: Creates a new #TRegEx object.
- about: @searchPattern is the regular expression with which to perform the search.
- End Rem
- Method New(searchPattern:String, options:TRegExOptions = Null)
- Self.searchPattern = searchPattern
- If options Then
- Self.options = options
- Else
- If Not defaultOptions Then
- defaultOptions = New TRegExOptions
- End If
- Self.options = defaultOptions
- End If
- End Method
-
- Rem
- bbdoc: Creates a new #TRegEx object.
- about: @searchPattern is the regular expression with which to perform the search.
- End Rem
- Function Create:TRegEx(searchPattern:String, options:TRegExOptions = Null)
- Return New TRegEx(searchPattern, options)
- End Function
- Rem
- bbdoc: Sets the default options for all new #TRegEx objects.
- about: This is useful if you want to set the options once and use them for all searches.
- End Rem
- Function SetDefaultOptions(options:TRegExOptions)
- defaultOptions = options
- End Function
-
- Rem
- bbdoc: Replaces all occurances of the search Pattern with @replaceWith on @target, from @startPos.
- returns: The newly replaced string.
- about: Doesn't affect the original @target contents.
- End Rem
- Method ReplaceAll:String(target:String, replaceWith:String, startPos:Size_T = 0)
- If Not options Then
- options = New TRegExOptions
- End If
- ' remember the current setting
- Local oldOpt:Int = options.replaceAllMatches
-
- ' enable global replace
- options.replaceAllMatches = True
-
- ' let Replace do all the work
- Local s:String = Replace(target, replaceWith, startPos)
-
- ' put back the "current" setting
- options.replaceAllMatches = oldOpt
-
- Return s
- End Method
-
- Rem
- bbdoc: Replaces the first occurance of the search Pattern with @replaceWith on @target, from @startPos.
- returns: The newly replaced string.
- about: To access a specific subquery during the replace, you can use the \n syntax in @replaceWith, where \0
- refers to the whole match, and \1 refers to the first subquery/group, and so on. <i>(see
- <a href="../tests/test_07.bmx">test_07</a> for an example)</i>.
- <p>Doesn't affect the original @target contents.</p>
- End Rem
- Method Replace:String(target:String, replaceWith:String, startPos:Size_T = 0)
- If Not options Then
- options = New TRegExOptions
- End If
- Local globalReplace:Int = options.replaceAllMatches
- ' the search pattern has changed !
- ' recompile
- ' this only happens very occasionally... (probably ;-)
- 'If lastPattern <> searchPattern Or Not pcre Then
- If Not compiled Then
- init()
- End If
- Local retString:String
-
- ' this is a new target...
- If target <> lastTarget Then
- lastTarget = target
-
- If TArg Then
- MemFree(TArg)
- End If
-
- TArg = target.toWString()
- targLength = target.length
- End If
- ' initial search...
- Local result:Int = pcre2_match_16(pcre, TArg, targLength, startPos, getExecOpt(), matchPtr, Null)
- ' if there wasn't an error... process the match (even for no-match)
- While result >= 0 Or result = PCRE2_ERROR_NOMATCH
- sizeOffsets = pcre2_get_ovector_count_16(matchPtr)
- offsets = pcre2_get_ovector_pointer_16(matchPtr)
- Local replaceStr:String = replaceWith
- Local ofs:Size_T Ptr = offsets
- For Local i:Int = 0 Until result
- Local idx:Int = i * 2
- replaceStr = replaceStr.Replace( "\" + i, lastTarget[ofs[idx]..ofs[idx+1]])
- Next
- If result > 0 Then
- ' add text so far, and the replacement
- retString:+ lastTarget[startPos..offsets[0]] + replaceStr
-
- Else
- ' search finished. Fill to the end
- retString:+ lastTarget[startPos..targLength]
- Exit
- End If
-
- ' set start to the end of the last match position
- startPos = offsets[1]
-
- ' only doing the first replace? Then we can exit now...
- If Not globalReplace Then
-
- ' all done. Fill to the end
- retString:+ lastTarget[startPos..targLength]
- Exit
- End If
-
- ' find the next match
- result = pcre2_match_16(pcre, TArg, targLength, startPos, getExecOpt(), matchPtr, Null)
- Wend
-
- Return retString ' convert back to max string
- End Method
-
- Rem
- bbdoc: Performs a search on the given @target from @startPos, using the search Pattern.
- returns: A #TRegExMatch object or Null if no matches found.
- about: If @target is <b>not</b> set, the search will use the <b>previous</b> @target.
- You will want to set @target the first time this method is called.<br>
- If you call this method with no parameters it will start the search from the end of the last search, effectively
- iterating through the target string.
- End Rem
- Method Find:TRegExMatch(target:String = Null)
- If Not options Then
- options = New TRegExOptions
- End If
- ' the search pattern has changed !
- ' recompile
- ' this only happens very occasionally... (probably ;-)
- 'If lastPattern <> searchPattern Or Not pcre Then
- If Not compiled Then
- init()
- End If
- Local startPos:Size_T
- ' no target specified, we are probably performing another search on the original target
- If Not target Then
-
- ' no lastTarget? Not allowed.
- If Not lastTarget Then
- Return Null
- End If
- startPos = lastEndPos
- Else
- ' this is a new target...
- If target <> lastTarget Then
- lastTarget = target
-
- If TArg Then
- MemFree(TArg)
- End If
-
- TArg = target.toWString()
- targLength = target.length
- End If
- End If
- Return DoFind(startPos)
- End Method
- Method DoFind:TRegExMatch(startPos:Size_T)
- Local result:Int = pcre2_match_16(pcre, TArg, targLength, startPos, getExecOpt(), matchPtr, Null)
-
- If result >= 0 Then
- sizeOffsets = pcre2_get_ovector_count_16(matchPtr)
- offsets = pcre2_get_ovector_pointer_16(matchPtr)
- Local match:TRegExMatch = New TRegExMatch(pcre, matchPtr)
- lastEndPos = offsets[1]
- Return match
- Else
- ' no point raising an exception when nothing found... we can just return a null object
- If result = PCRE2_ERROR_NOMATCH Then
- Return Null
- End If
-
- ' there was an error of some kind... throw it!
- Throw TRegExException.Raise(result)
- End If
- End Method
- Rem
- bbdoc: Performs a search on the given @target from @startPos, using the search Pattern.
- returns: A #TRegExMatch object or Null if no matches found.
- End Rem
- Method Find:TRegExMatch(target:String, startPos:Size_T)
-
- If Not options Then
- options = New TRegExOptions
- End If
- ' the search pattern has changed !
- ' recompile
- ' this only happens very occasionally... (probably ;-)
- 'If lastPattern <> searchPattern Or Not pcre Then
- If Not compiled Then
- init()
- End If
- ' no target specified, we are probably performing another search on the original target
- If Not target Then
-
- ' no lastTarget? Not allowed.
- If Not lastTarget Then
- Return Null
- End If
-
- ' no startPos? then we'll start from the end of the last search point
- If startPos < 0 Then
- startPos = lastEndPos
- End If
- Else
- ' this is a new target...
- If target <> lastTarget Then
- lastTarget = target
-
- If TArg Then
- MemFree(TArg)
- End If
-
- TArg = target.toWString()
- targLength = target.length
- End If
- End If
- ' set the startPos to 0 if not already set
- If startPos < 0 Then
- startPos = 0
- End If
-
- Return DoFind(startPos)
- End Method
-
- ' resets and recompiles the regular expression
- Method init()
- lastPattern = searchPattern
-
- Local pat:Short Ptr = lastPattern.ToWString()
- Local errorcode:Int
- Local erroffset:Size_T
- Local bptr:Byte Ptr = pcre2_compile_16(pat, Size_T(lastPattern.length), getCompileOpt(), Varptr errorcode, ..
- Varptr erroffset, Null)
- MemFree(pat)
-
- If bptr Then
- If pcre
- MemFree(pcre)
- EndIf
-
- pcre = bptr
- Else
- Local buffer:Short[256]
- pcre2_get_error_message_16(errorcode, buffer, 256)
- Throw TRegExException.Raise(-99, String.fromWString(buffer))
- End If
- Local jitOptions:Int = getJITOpt()
- If jitOptions Then
- Local result:Int = pcre2_jit_compile_16(pcre, jitOptions)
- End If
-
- If matchPtr Then
- pcre2_match_data_free_16(matchPtr)
- End If
- matchPtr = pcre2_match_data_create_from_pattern_16(pcre, Null)
-
- compiled = True
- End Method
-
- ' possible options for compiling
- Method getCompileOpt:Int()
- Local opt:Int = PCRE2_UTF
- If options.onlyPatternOptions Then
- Return opt
- End If
-
- If Not options.caseSensitive Then
- opt:| PCRE2_CASELESS
- End If
-
- If options.dotMatchAll Then
- opt:| PCRE2_DOTALL
- End If
-
- If Not options.greedy Then
- opt:| PCRE2_UNGREEDY
- End If
-
- Select options.lineEndType
- Case 1
- opt:| PCRE2_NEWLINE_CR
- Case 2
- opt:| PCRE2_NEWLINE_LF
- Case 3
- opt:| PCRE2_NEWLINE_CRLF
- Default
- opt:| PCRE2_NEWLINE_ANY
- End Select
-
- If Not options.matchEmpty Then
- opt:| PCRE2_NOTEMPTY
- End If
-
- If options.targetIsMultiline Then
- opt:| PCRE2_MULTILINE
- End If
-
- If options.dollarEndOnly Then
- opt:| PCRE2_DOLLAR_ENDONLY
- End If
-
- If options.extended Then
- opt:| PCRE2_EXTENDED
- End If
-
- Return opt
- End Method
-
- ' possible options for execution
- Method getExecOpt:Int()
- Local opt:Int
- If options.onlyPatternOptions Then
- Return opt
- End If
-
- Select options.lineEndType
- Case 1
- opt:| PCRE2_NEWLINE_CR
- Case 2
- opt:| PCRE2_NEWLINE_LF
- Case 3
- opt:| PCRE2_NEWLINE_CRLF
- Default
- opt:| PCRE2_NEWLINE_ANY
- End Select
- If Not options.matchEmpty Then
- opt:| PCRE2_NOTEMPTY
- End If
-
- If Not options.stringIsLineBeginning Then
- opt:| PCRE2_NOTBOL
- End If
-
- If Not options.stringIsLineEnding Then
- opt:| PCRE2_NOTEOL
- End If
-
- Return opt
- End Method
-
- ' possible options for jit
- Method getJITOpt:Int()
- Local opt:Int
- If options.onlyPatternOptions Then
- Return opt
- End If
-
- If options.jitComplete Then
- opt :| PCRE2_JIT_COMPLETE
- End If
- If options.jitPartialSoft Then
- opt :| PCRE2_JIT_PARTIAL_SOFT
- End If
- If options.jitPartialHard Then
- opt :| PCRE2_JIT_PARTIAL_HARD
- End If
-
- End Method
- Rem
- bbdoc: Returns which optional features are available.
- End Rem
- Function Config:Int(what:Int, where_:Int Var)
- If what <> PCRE2_CONFIG_UNICODE_VERSION And what <> PCRE2_CONFIG_VERSION Then
- Return pcre2_config_16(what, Varptr where_)
- End If
- Return PCRE2_ERROR_BADOPTION
- End Function
- End Type
- Rem
- bbdoc: Used to extract the matched string when doing a search with regular expressions.
- End Rem
- Type TRegExMatch
- Private
- Field pcre:Byte Ptr
- Field matchPtr:Byte Ptr
- Field count:UInt
- Method New(pcre:Byte Ptr, matchPtr:Byte Ptr)
- Self.pcre = pcre
- Self.matchPtr = matchPtr
- Self.count = pcre2_get_ovector_count_16(matchPtr)
- End Method
- Public
- Rem
- bbdoc: Returns the number of subexpressions as a result of the search.
- End Rem
- Method SubCount:Int()
- Return count
- End Method
-
- Rem
- bbdoc: Returns the subexpression for @matchNumber.
- returns: The matched string, the subexpression string, or "" if @matchNumber is out of range.
- about: For expressions with no subpattern groups, this method can be used without
- a parameter to return the matched string.
- End Rem
- Method SubExp:String(matchNumber:Int = 0)
- Local _subExpr:String
-
- If matchNumber >= 0 And matchNumber < count Then
- Local sPtr:Short Ptr
- Local sLen:Size_T
- Local result:Int = pcre2_substring_get_bynumber_16(matchPtr, matchNumber, Varptr sPtr, Varptr sLen)
- If Not result Then
- _subExpr = String.FromShorts(sPtr, Int(sLen))
- pcre2_substring_free_16(sPtr)
- End If
- End If
-
-
- Return _subExpr
- End Method
-
- Rem
- bbdoc: Returns the start position for subexpression @matchNumber.
- returns: The start position, or -1 if @matchNumber is out of range.
- about: For expressions with no subpattern groups, this method can be used without a parameter
- to return the start position of the matched string.
- End Rem
- Method SubStart:Int(matchNumber:Int = 0)
- If matchNumber >= 0 And matchNumber < count Then
- Local offsets:Size_T Ptr = pcre2_get_ovector_pointer_16(matchPtr)
- Return offsets[matchNumber]
- End If
- Return -1
- End Method
- Rem
- bbdoc: Returns the end position for subexpression @matchNumber.
- returns: The end position, or -1 if @matchNumber is out of range.
- about: For expressions with no subpattern groups, this method can be used without a parameter
- to return the end position of the matched string.
- End Rem
- Method SubEnd:Int(matchNumber:Int = 0)
- If matchNumber >= 0 And matchNumber < count Then
- Local offsets:Size_T Ptr = pcre2_get_ovector_pointer_16(matchPtr)
- Return offsets[matchNumber + 1] - 1
- End If
- Return -1
- End Method
-
- Rem
- bbdoc: Returns the subexpression for the given @name.
- returns: The matched string, the subexpression string, or "" if @matchNumber is out of range.
- End Rem
- Method SubExp:String(name:String)
- Return SubExpByName(name)
- End Method
- Rem
- bbdoc: Returns the subexpression for the given @name.
- returns: The matched string, the subexpression string, or "" if @matchNumber is out of range.
- End Rem
- Method SubExpByName:String(name:String)
- Local _subExpr:String
- If name Then
- Local sPtr:Short Ptr
- Local sLen:Size_T
- Local n:Short Ptr = name.ToWString()
- Local result:Int = pcre2_substring_get_byname_16(matchPtr, n, Varptr sPtr, Varptr sLen)
- MemFree(n)
- If Not result Then
- _subExpr = String.FromShorts(sPtr, Int(sLen))
-
- pcre2_substring_free_16(sPtr)
- End If
- End If
-
- Return _subExpr
- End Method
- Rem
- bbdoc: Returns the index of the subexpression for the given @name.
- End Rem
- Method SubIndex:Int(name:String)
- Return SubIndexByName(name)
- End Method
- Rem
- bbdoc: Returns the index of the subexpression for the given @name.
- End Rem
- Method SubIndexByName:Int(name:String)
- If name Then
- Local n:Short Ptr = name.ToWString()
- Local index:Int = pcre2_substring_number_from_name_16(pcre, n)
- MemFree(n)
-
- If index >= 0 Then
- Return index
- End If
- End If
- Return -1
- End Method
- Rem
- bbdoc: Returns the start position of the subexpression for the given @name.
- End Rem
- Method SubStart:Int(name:String)
- Return SubStartByName(name)
- End Method
- Rem
- bbdoc: Returns the start position of the subexpression for the given @name.
- End Rem
- Method SubStartByName:Int(name:String)
- If name Then
- Local n:Short Ptr = name.ToWString()
- Local index:Int = pcre2_substring_number_from_name_16(pcre, n)
- MemFree(n)
-
- If index >= 0 Then
- Local offsets:Size_T Ptr = pcre2_get_ovector_pointer_16(matchPtr)
- Return offsets[index]
- End If
- End If
- Return -1
- End Method
- Rem
- bbdoc: Returns the end position of the subexpression for the given @name.
- End Rem
- Method SubEnd:Int(name:String)
- Return SubEndByName(name)
- End Method
- Rem
- bbdoc: Returns the end position of the subexpression for the given @name.
- End Rem
- Method SubEndByName:Int(name:String)
- If name Then
- Local n:Short Ptr = name.ToWString()
- Local index:Int = pcre2_substring_number_from_name_16(pcre, n)
- MemFree(n)
-
- If index >= 0 Then
- Local offsets:Size_T Ptr = pcre2_get_ovector_pointer_16(matchPtr)
- Return offsets[index + 1] - 1
- End If
- End If
- Return -1
- End Method
-
- End Type
- Rem
- bbdoc: Specifies options used when performing searches.
- End Rem
- Type TRegExOptions
- Rem
- bbdoc: Ignore other options and use only the pattern's options, like case sensitivity, etc.
- End Rem
- Field onlyPatternOptions:Int = False
- Rem
- bbdoc: Whether matches are case sensitive.
- End Rem
- Field caseSensitive:Int = False
- Rem
- bbdoc: Allow dot (period) to match new lines as well as everything else.
- about: False indicates dot doesn't match new lines.
- End Rem
- Field dotMatchAll:Int = False
- Rem
- bbdoc: Greedy matches everything from the beginning of the first delimeter to the end of the last delimiter, and everything in between.
- about:
- End Rem
- Field greedy:Int = True
- Rem
- bbdoc: Determines how new lines are interpreted.
- about:
- <ul>
- <li>0 - any line ending</li>
- <li>1 - \r</li>
- <li>2 - \n</li>
- <li>3 - \r\n</li>
- </ul>
- End Rem
- Field lineEndType:Int = 0
- Rem
- bbdoc: Allow patterns to match empty strings.
- End Rem
- Field matchEmpty:Int = True
- 'Rem
- 'bbdoc: Indicates whether all occurances of matches will be replaced.
- 'about: Only applicable during a Replace.
- 'End Rem
- Field replaceAllMatches:Int = False
- Rem
- bbdoc: Count the beginning of a string as the beginning of a line.
- End Rem
- Field stringIsLineBeginning:Int = True
- Rem
- bbdoc: Count the end of a string as the end of a line.
- End Rem
- Field stringIsLineEnding:Int = True
- Rem
- bbdoc: Matches internal new lines against ^ and $.
- about: Set to false to ignore internal new lines.
- End Rem
- Field targetIsMultiline:Int = True
- Rem
- bbdoc: Dollar ($) matches newline at end.
- about: Set to True for dollar to only match the end of the string, otherwise
- matches a newline before the end of the string.
- End Rem
- Field dollarEndOnly:Int = False
- Rem
- bbdoc: Ignore whitespace and # comments.
- about: When set to True, whitespace in the pattern (other than in a character class) and
- characters between a # outside a character class and the next newline are ignored.<br>
- An escaping backslash can be used to include a whitespace or # character as part of the pattern.
- End Rem
- Field extended:Int = False
- Rem
- bbdoc: Compile code for full matching.
- about: When set to True, the JIT compiler is enabled.
- End Rem
- Field jitComplete:Int = False
- Rem
- bbdoc: Compile code For soft partial matching.
- about: When set to True, the JIT compiler is enabled.
- End Rem
- Field jitPartialSoft:Int = False
- Rem
- bbdoc: Compile code for hard partial matching.
- about: When set to True, the JIT compiler is enabled.
- End Rem
- Field jitPartialHard:Int = False
- End Type
- Rem
- bbdoc: A Regular Expression exception.
- about: This can be thrown either during regular expression compilation (-99) or during a search (-1 to -23).
- End Rem
- Type TRegExException
- Rem
- bbdoc: The type of error thrown.
- about: -99 is a regular expression compile error. Read #message for details.<br>
- -1 to -23 is thrown during a search. Read #message for details.
- End Rem
- Field num:Int
- Rem
- bbdoc: The error text.
- End Rem
- Field message:String
-
- Function Raise:TRegExException(num:Int, message:String = Null)
- Local this:TRegExException = New TRegExException
-
- If message Then
- this.message = message
- Else
- this.message = this.getFromNum(num)
- End If
-
- this.num = num
- Return this
- End Function
-
- Rem
- bbdoc: Returns the exception as a String.
- End Rem
- Method toString:String()
- Return "( " + num + " ) " + message
- End Method
-
- Method getFromNum:String(err:Int)
- Select err
- Case -1
- Return "No Match"
- Case -2
- Return "PCRE2_ERROR_PARTIAL"
- Case -3
- Return "PCRE2_ERROR_UTF8_ERR1"
- Case -4
- Return "PCRE2_ERROR_UTF8_ERR2"
- Case -5
- Return "PCRE2_ERROR_UTF8_ERR3"
- Case -6
- Return "PCRE2_ERROR_UTF8_ERR4"
- Case -7
- Return "PCRE2_ERROR_UTF8_ERR5"
- Case -8
- Return "PCRE2_ERROR_UTF8_ERR6"
- Case -9
- Return "PCRE2_ERROR_UTF8_ERR7"
- Case -10
- Return "PCRE2_ERROR_UTF8_ERR8"
- Case -11
- Return "PCRE2_ERROR_UTF8_ERR9"
- Case -12
- Return "PCRE2_ERROR_UTF8_ERR10"
- Case -13
- Return "PCRE2_ERROR_UTF8_ERR11"
- Case -14
- Return "PCRE2_ERROR_UTF8_ERR12"
- Case -15
- Return "PCRE2_ERROR_UTF8_ERR13"
- Case -16
- Return "PCRE2_ERROR_UTF8_ERR14"
- Case -17
- Return "PCRE2_ERROR_UTF8_ERR15"
- Case -18
- Return "PCRE2_ERROR_UTF8_ERR16"
- Case -19
- Return "PCRE2_ERROR_UTF8_ERR17"
- Case -20
- Return "PCRE2_ERROR_UTF8_ERR18"
- Case -21
- Return "PCRE2_ERROR_UTF8_ERR19"
- Case -22
- Return "PCRE2_ERROR_UTF8_ERR20"
- Case -23
- Return "PCRE2_ERROR_UTF8_ERR21"
- Case -24
- Return "PCRE2_ERROR_UTF16_ERR1"
- Case -25
- Return "PCRE2_ERROR_UTF16_ERR2"
- Case -26
- Return "PCRE2_ERROR_UTF16_ERR3"
- Case -27
- Return "PCRE2_ERROR_UTF32_ERR1"
- Case -28
- Return "PCRE2_ERROR_UTF32_ERR2"
- Case -29
- Return "PCRE2_ERROR_BADDATA"
- Case -30
- Return "PCRE2_ERROR_BADLENGTH"
- Case -31
- Return "PCRE2_ERROR_BADMAGIC"
- Case -32
- Return "PCRE2_ERROR_BADMODE"
- Case -33
- Return "PCRE2_ERROR_BADOFFSET"
- Case -34
- Return "PCRE2_ERROR_BADOPTION"
- Case -35
- Return "PCRE2_ERROR_BADREPLACEMENT"
- Case -36
- Return "PCRE2_ERROR_BADUTFOFFSET"
- Case -37
- Return "PCRE2_ERROR_CALLOUT"
- Case -38
- Return "PCRE2_ERROR_DFA_BADRESTART"
- Case -39
- Return "PCRE2_ERROR_DFA_RECURSE"
- Case -40
- Return "PCRE2_ERROR_DFA_UCOND"
- Case -41
- Return "PCRE2_ERROR_DFA_UFUNC"
- Case -42
- Return "PCRE2_ERROR_DFA_UITEM"
- Case -43
- Return "PCRE2_ERROR_DFA_WSSIZE"
- Case -44
- Return "PCRE2_ERROR_INTERNAL"
- Case -45
- Return "PCRE2_ERROR_JIT_BADOPTION"
- Case -46
- Return "PCRE2_ERROR_JIT_STACKLIMIT"
- Case -47
- Return "PCRE2_ERROR_MATCHLIMIT"
- Case -48
- Return "PCRE2_ERROR_NOMEMORY"
- Case -49
- Return "PCRE2_ERROR_NOSUBSTRING"
- Case -50
- Return "PCRE2_ERROR_NOUNIQUESUBSTRING"
- Case -51
- Return "PCRE2_ERROR_NULL"
- Case -52
- Return "PCRE2_ERROR_RECURSELOOP"
- Case -53
- Return "PCRE2_ERROR_RECURSIONLIMIT"
- Case -54
- Return "PCRE2_ERROR_UNAVAILABLE"
- Case -55
- Return "PCRE2_ERROR_UNSET"
- End Select
- End Method
-
- End Type
|