| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- import re
- import json
- def parse_nested_param(string, level):
- """
- Generate strings contained in nested (), indexing i = level
- """
- if len(re.findall("\(", string)) == len(re.findall("\)", string)):
- LeftRightIndex = [x for x in zip(
- [Left.start()+1 for Left in re.finditer('\(', string)],
- reversed([Right.start() for Right in re.finditer('\)', string)]))]
- elif len(re.findall("\(", string)) > len(re.findall("\)", string)):
- return parse_nested_param(string + ')', level)
- elif len(re.findall("\(", string)) < len(re.findall("\)", string)):
- return parse_nested_param('(' + string, level)
- else:
- return 'Failed to parse params'
- try:
- return [string[LeftRightIndex[level][0]:LeftRightIndex[level][1]]]
- except IndexError:
- return [string[LeftRightIndex[level+1][0]:LeftRightIndex[level+1][1]]]
- # Parses the deepest part
- def maxDepth(S):
- current_max = 0
- max = 0
- n = len(S)
-
- # Traverse the input string
- for i in range(n):
- if S[i] == '(':
- current_max += 1
-
- if current_max > max:
- max = current_max
- elif S[i] == ')':
- if current_max > 0:
- current_max -= 1
- else:
- return -1
-
- # finally check for unbalanced string
- if current_max != 0:
- return -1
-
- return max-1
- def parse_type(data, thistype):
- if data == None:
- return "Empty"
- if "int" in thistype:
- try:
- return int(data)
- except ValueError:
- print("ValueError while casting %s" % data)
- return data
- if "lower" in thistype:
- return data.lower()
- if "upper" in thistype:
- return data.upper()
- if "trim" in thistype:
- return data.strip()
- if "strip" in thistype:
- return data.strip()
- if "split" in thistype:
- # Should be able to split anything
- return data.split()
- if "len" in thistype or "length" in thistype:
- return len(data)
- if "parse" in thistype:
- splitvalues = []
- default_error = """Error. Expected syntax: parse(["hello","test1"],0:1)"""
- if "," in data:
- splitvalues = data.split(",")
- for item in range(len(splitvalues)):
- splitvalues[item] = splitvalues[item].strip()
- else:
- return default_error
- lastsplit = []
- if ":" in splitvalues[-1]:
- lastsplit = splitvalues[-1].split(":")
- else:
- try:
- lastsplit = [int(splitvalues[-1])]
- except ValueError:
- return default_error
- try:
- parsedlist = ",".join(splitvalues[0:-1])
- print(parsedlist)
- print(lastsplit)
- if len(lastsplit) > 1:
- tmp = json.loads(parsedlist)[int(lastsplit[0]):int(lastsplit[1])]
- else:
- tmp = json.loads(parsedlist)[lastsplit[0]]
- print(tmp)
- return tmp
- except IndexError as e:
- return default_error
- # Parses the INNER value and recurses until everything is done
- def parse_wrapper(data):
- try:
- if "(" not in data or ")" not in data:
- return data
- except TypeError:
- return data
- print("Running %s" % data)
- # Look for the INNER wrapper first, then move out
- wrappers = ["int", "number", "lower", "upper", "trim", "strip", "split", "parse", "len", "length"]
- found = False
- for wrapper in wrappers:
- if wrapper not in data.lower():
- continue
- found = True
- break
- if not found:
- return data
- # Do stuff here.
- innervalue = parse_nested_param(data, maxDepth(data)-0)
- outervalue = parse_nested_param(data, maxDepth(data)-1)
- print("INNER: ", outervalue)
- print("OUTER: ", outervalue)
- if outervalue != innervalue:
- #print("Outer: ", outervalue, " inner: ", innervalue)
- for key in range(len(innervalue)):
- # Replace OUTERVALUE[key] with INNERVALUE[key] in data.
- print("Replace %s with %s in %s" % (outervalue[key], innervalue[key], data))
- data = data.replace(outervalue[key], innervalue[key])
- else:
- for thistype in wrappers:
- if thistype not in data.lower():
- continue
- parsed_value = parse_type(innervalue[0], thistype)
- return parsed_value
- print("DATA: %s\n" % data)
- return parse_wrapper(data)
- def parse_wrapper_start(data):
- newdata = []
- newstring = ""
- record = True
- paranCnt = 0
- for char in data:
- if char == "(":
- paranCnt += 1
- if not record:
- record = True
- if record:
- newstring += char
- if paranCnt == 0 and char == " ":
- newdata.append(newstring)
- newstring = ""
- record = True
- if char == ")":
- paranCnt -= 1
- if paranCnt == 0:
- record = False
- if len(newstring) > 0:
- newdata.append(newstring)
- parsedlist = []
- non_string = False
- for item in newdata:
- ret = parse_wrapper(item)
- if not isinstance(ret, str):
- non_string = True
- parsedlist.append(ret)
- if len(parsedlist) > 0 and not non_string:
- return " ".join(parsedlist)
- elif len(parsedlist) == 1 and non_string:
- return parsedlist[0]
- else:
- print("Casting back to string because multi: ", parsedlist)
- newlist = []
- for item in parsedlist:
- try:
- newlist.append(str(item))
- except ValueError:
- newlist.append("parsing_error")
- return " ".join(newlist)
- data = "split(hello there)"
- data = """parse(["testing", "what", "is this"], 0:2)"""
- #data = "int(int(2))"
- print("RET: ", parse_wrapper_start(data))
|