--!movie
--!encoding=utf-8
--****************************************************************************
-- @file Regular Expression Wrapper based on QtWidgets Xtra (+OOP framework) - UNTESTED CODE!!!
-- @author Valentin Schmidt
-- @version 0.2
--****************************************************************************
global $
----------------------------------------
-- Counts the pattern matches in string.
-- Optional parameter matches (list) is filled with matches (indexed by back ref number)
--
-- @param {string} patt - The search pattern
-- @param {string} str - The input string
-- @param {list} [matches=void] - Optional, if specified, filled with matches
-- @param {bool} [caseInsensitive=false] - Optional, default = false = case-sensitive
-- @returns {number} Number of matches
----------------------------------------
on regex_search (patt, str, matches, caseInsensitive)
if voidP(caseInsensitive) then caseInsensitive=0
rx = $.Qt.RegExp.new(patt, caseInsensitive=0)
rx.indexIn(str)
res = rx.capturedTexts()
if listP(matches) then
repeat with str in res
matches.add(str)
end repeat
end if
return res.count
end
----------------------------------------
-- Replaces all pattern matches with replacement string
--
-- @param {string} patt - The search pattern
-- @param {string} replStr - The replacement string
-- @param {string} str - The input string
-- @param {bool} [caseInsensitive=false] - Optional, default = false = case-sensitive
-- @returns {string} The new string
----------------------------------------
on regex_replace (patt, replStr, str, caseInsensitive)
if voidP(caseInsensitive) then caseInsensitive=0
rx = $.Qt.RegExp.new(patt, caseInsensitive=0)
return rx.replace(str, replStr)
end
----------------------------------------
-- Replaces all pattern matches with replacement string according to "hash" (propertyList or Object)
-- Usage: put regexp_replace_hash("#(\d+)#", ["1":"X","2":"Y"], "aaa#1#bbb#2#ccc") -> "aaaXbbbYccc"
--
-- @param {string} patt - The search pattern
-- @param {propList|Object} hash
-- @param {string} str - The input string
-- @param {number} [num=0] - Index of back reference containing the index string
-- @param {bool} [caseInsensitive=false] - Optional, default = false = case-sensitive
-- @returns {string} The new string
----------------------------------------
on regexp_replace_hash (patt, hash, str, num, caseInsensitive)
if voidP(num) then num=0
if voidP(caseInsensitive) then caseInsensitive=0
rx = $.Qt.RegExp.new(patt, caseInsensitive=0)
pos = 0
matches = []
repeat while true
rx.indexIn(str, pos)
pos = rx.pos(num)
if pos<0 then exit repeat
len = rx.matchedLength()
matches.add([pos, len])
pos = pos + len
end repeat
res = str
cnt = count(matches)
repeat with i = cnt down to 1
pos = matches[i][1]
len = matches[i][2]
s = str.char[pos+1..pos+len]
n = hash.findPos(s)
if n>0 then
put hash[n] into char (pos+1) to (pos+len) of res
end if
end repeat
return res
end
----------------------------------------
-- Replaces pattern matches in string with callback results based on match
-- Usage: put regexp_replace_callback("&#([0-9]+);", str, #_ord_to_utf8, me, 1) ->
--
-- @param {string} patt - The search pattern
-- @param {string} str - The input string
-- @param {symbol} cbHandler
-- @param {Object} [cbObject=_movie]
-- @param {number} [num=0] - Index of argument passed to callback
-- @param {bool} [caseInsensitive=false] - Optional, default = false = case-sensitive
-- @returns {string} The new string
----------------------------------------
on regexp_replace_callback (patt, str, cbHandler, cbObject, num, caseInsensitive)
if voidP(cbObject) then cbObject=_movie
if voidP(num) then num=0
if voidP(caseInsensitive) then caseInsensitive=0
rx = $.Qt.RegExp.new(patt, caseInsensitive=0)
pos = 0
matches = []
repeat while true
rx.indexIn(str, pos)
pos = rx.pos(num)
if pos<0 then exit repeat
len = rx.matchedLength()
matches.add([pos, len])
pos = pos + len
end repeat
res = str
cnt = count(matches)
repeat with i = cnt down to 1
pos = matches[i][1]
len = matches[i][2]
s = str.char[pos+1..pos.len]
repl = _movie.call(cbHandler, [cbObject], s)
if not voidP(repl) then
put repl into char (pos+1) to (pos+len) of res
end if
end repeat
return res
end
----------------------------------------
-- Splits string based on RegExp pattern, returns list
--
-- @param {string} patt - The pattern used for splitting
-- @param {string} str - The input string
-- @param {bool} [caseInsensitive=false] - Optional, default = false = case-sensitive
-- @returns {list}
----------------------------------------
on regex_split (patt, str, caseInsensitive)
if voidP(caseInsensitive) then caseInsensitive=0
rx = $.Qt.RegExp.new(patt, caseInsensitive=0)
return rx.split(str)
end
--**************************************
-- String functions implemented via RegExp
--**************************************
----------------------------------------
-- Replaces all occurences of stringToFind with stringToInsert, returns new string
--
-- @param {string} stringToFind
-- @param {string} stringToInsert
-- @param {string} str - The input string
-- @param {bool} [caseInsensitive=false] - Optional, default = false = case-sensitive
-- @returns {string} The new string
----------------------------------------
on str_replace (stringToFind, stringToInsert, str, caseInsensitive)
stringToFind = $.Qt.RegExp.escape(stringToFind)
stringToInsert = $.Qt.RegExp.escape(stringToInsert) -- ??? only escape \1 etc?
return regex_replace (stringToFind, stringToInsert, str, caseInsensitive)
end
----------------------------------------
-- Splits string based on delimter string, returns list
--
-- @param {string} delim - The string delimiter used for splitting
-- @param {string} str - The input string
-- @param {bool} [caseInsensitive=false] - Optional, default = false = case-sensitive
-- @returns {list}
----------------------------------------
on explode (delim, str, caseInsensitive)
delim = $.Qt.RegExp.escape(delim)
return regex_split (delim, str, caseInsensitive)
end
----------------------------------------
-- Returns number of occurences of string needle in string haystack
--
-- @param {string} haystack
-- @param {string} needle
-- @param {bool} [caseInsensitive=false] - Optional, default = false = case-sensitive
-- @returns {number}
----------------------------------------
on substr_count (haystack, needle, caseInsensitive)
needle = $.Qt.RegExp.escape(needle)
return regex_search (needle, haystack, void, caseInsensitive)
end
----------------------------------------
-- lower to upper case
----------------------------------------
on strtoupper (str)
strFrom = "abcdefghijklmnopqrstuvwxyzäöü"
strTo = "ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜ"
patt = ""
hash = [:]
repeat with i = 1 to 29
hash[strFrom.char[i]] = strTo.char[i]
put strFrom.char[i]&"|" after patt
end repeat
delete the last char of patt
return regexp_replace_hash (patt, hash, str)
end
----------------------------------------
-- upper to lower case
----------------------------------------
on strtolower (str)
strFrom = "ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜ"
strTo = "abcdefghijklmnopqrstuvwxyzäöü"
patt = ""
hash = [:]
repeat with i = 1 to 29
hash[strFrom.char[i]] = strTo.char[i]
put strFrom.char[i]&"|" after patt
end repeat
delete the last char of patt
return regexp_replace_hash (patt, hash, str)
end