# coding=utf8
# the above tag defines encoding for this document and is for Python 2.x compatibility
import re
regex = (r"(?x)\n"
r".+(?:Sub|Function)\ (\w+)\( # method declaration\n"
r"(?: # start of parameter pattern\n"
r"[\w\W]*?(?<=\b) # parameter may be preceded by ByVal or Optional keywords\n"
r"([a-z]\w+)+ # parameter starts with a lower case\n"
r".*? # parameter may be followed by its type declaration\n"
r"(?:=\ ([^\,]+)){0,1} # optional parameters may be followed by default value, it is captured to be used in method call\n"
r"(?:,|\)) # parameter is followed by , or )\n"
r"){0,1} # end of parameter pattern (may be copy-pasted infinitely to capture all parameters)\n"
r"(?: # start of parameter pattern\n"
r"[\w\W]*?(?<=\b) # parameter may be preceded by ByVal or Optional keywords\n"
r"([a-z]\w+)+ # parameter starts with a lower case\n"
r".*? # parameter may be followed by its type declaration\n"
r"(?:=\ ([^\,]+)){0,1} # optional parameters may be followed by default value, it is captured to be used in method call\n"
r"(?:,|\)) # parameter is followed by , or )\n"
r"){0,1} # end of parameter pattern (may be copy-pasted infinitely to capture all parameters)\n"
r"(?: # start of parameter pattern\n"
r"[\w\W]*?(?<=\b) # parameter may be preceded by ByVal or Optional keywords\n"
r"([a-z]\w+)+ # parameter starts with a lower case\n"
r".*? # parameter may be followed by its type declaration\n"
r"(?:=\ ([^\,]+)){0,1} # optional parameters may be followed by default value, it is captured to be used in method call\n"
r"(?:,|\)) # parameter is followed by , or )\n"
r"){0,1} # end of parameter pattern (may be copy-pasted infinitely to capture all parameters)\n"
r"(?: # start of parameter pattern\n"
r"[\w\W]*?(?<=\b) # parameter may be preceded by ByVal or Optional keywords\n"
r"([a-z]\w+)+ # parameter starts with a lower case\n"
r".*? # parameter may be followed by its type declaration\n"
r"(?:=\ ([^\,]+)){0,1} # optional parameters may be followed by default value, it is captured to be used in method call\n"
r"(?:,|\)) # parameter is followed by , or )\n"
r"){0,1} # end of parameter pattern (may be copy-pasted infinitely to capture all parameters)\n"
r"(?: # start of parameter pattern\n"
r"[\w\W]*?(?<=\b) # parameter may be preceded by ByVal or Optional keywords\n"
r"([a-z]\w+)+ # parameter starts with a lower case\n"
r".*? # parameter may be followed by its type declaration\n"
r"(?:=\ ([^\,]+)){0,1} # optional parameters may be followed by default value, it is captured to be used in method call\n"
r"(?:,|\)) # parameter is followed by , or )\n"
r"){0,1} # end of parameter pattern (may be copy-pasted infinitely to capture all parameters)\n"
r"(?: # start of parameter pattern\n"
r"[\w\W]*?(?<=\b) # parameter may be preceded by ByVal or Optional keywords\n"
r"([a-z]\w+)+ # parameter starts with a lower case\n"
r".*? # parameter may be followed by its type declaration\n"
r"(?:=\ ([^\,]+)){0,1} # optional parameters may be followed by default value, it is captured to be used in method call\n"
r"(?:,|\)) # parameter is followed by , or )\n"
r"){0,1} # end of parameter pattern (may be copy-pasted infinitely to capture all parameters)\n"
r"(?: # start of parameter pattern\n"
r"[\w\W]*?(?<=\b) # parameter may be preceded by ByVal or Optional keywords\n"
r"([a-z]\w+)+ # parameter starts with a lower case\n"
r".*? # parameter may be followed by its type declaration\n"
r"(?:=\ ([^\,]+)){0,1} # optional parameters may be followed by default value, it is captured to be used in method call\n"
r"(?:,|\)) # parameter is followed by , or )\n"
r"){0,1} # end of parameter pattern (may be copy-pasted infinitely to capture all parameters)\n"
r"(?: # start of parameter pattern\n"
r"[\w\W]*?(?<=\b) # parameter may be preceded by ByVal or Optional keywords\n"
r"([a-z]\w+)+ # parameter starts with a lower case\n"
r".*? # parameter may be followed by its type declaration\n"
r"(?:=\ ([^\,]+)){0,1} # optional parameters may be followed by default value, it is captured to be used in method call\n"
r"(?:,|\)) # parameter is followed by , or )\n"
r"){0,1} # end of parameter pattern (may be copy-pasted infinitely to capture all parameters)\n"
r"(?: # start of parameter pattern\n"
r"[\w\W]*?(?<=\b) # parameter may be preceded by ByVal or Optional keywords\n"
r"([a-z]\w+)+ # parameter starts with a lower case\n"
r".*? # parameter may be followed by its type declaration\n"
r"(?:=\ ([^\,]+)){0,1} # optional parameters may be followed by default value, it is captured to be used in method call\n"
r"(?:,|\)) # parameter is followed by , or )\n"
r"){0,1} # end of parameter pattern (may be copy-pasted infinitely to capture all parameters)\n"
r"(?: # start of parameter pattern\n"
r"[\w\W]*?(?<=\b) # parameter may be preceded by ByVal or Optional keywords\n"
r"([a-z]\w+)+ # parameter starts with a lower case\n"
r".*? # parameter may be followed by its type declaration\n"
r"(?:=\ ([^\,]+)){0,1} # optional parameters may be followed by default value, it is captured to be used in method call\n"
r"(?:,|\)) # parameter is followed by , or )\n"
r"){0,1} # end of parameter pattern (may be copy-pasted infinitely to capture all parameters)\n"
r"(?: # start of parameter pattern\n"
r"[\w\W]*?(?<=\b) # parameter may be preceded by ByVal or Optional keywords\n"
r"([a-z]\w+)+ # parameter starts with a lower case\n"
r".*? # parameter may be followed by its type declaration\n"
r"(?:=\ ([^\,]+)){0,1} # optional parameters may be followed by default value, it is captured to be used in method call\n"
r"(?:,|\)) # parameter is followed by , or )\n"
r"){0,1} # end of parameter pattern (may be copy-pasted infinitely to capture all parameters)\n"
r"(?: # start of parameter pattern\n"
r"[\w\W]*?(?<=\b) # parameter may be preceded by ByVal or Optional keywords\n"
r"([a-z]\w+)+ # parameter starts with a lower case\n"
r".*? # parameter may be followed by its type declaration\n"
r"(?:=\ ([^\,]+)){0,1} # optional parameters may be followed by default value, it is captured to be used in method call\n"
r"(?:,|\)) # parameter is followed by , or )\n"
r"){0,1} # end of parameter pattern (may be copy-pasted infinitely to capture all parameters)\n")
test_str = ("Public Function BrowseToDictTreeNode(ByVal rootNode As Scripting.Dictionary, ByVal browseKey As String, ByVal nodeUrl As String, _\n"
" Optional ByVal urlSlash As String = \"/\", Optional ByVal childrenKey As String = \"Children\", _\n"
" Optional ByVal startAtLevel As Integer = 1) As Scripting.Dictionary\n")
subst = "#Sub call\\n$1 $2:=$3, $4:=$5, $6:=$7, $8:=$9, $10:=$11, $12:=$13, $14:=$15, $16:=$17, $18:=$19, $20:=$21, $20:=$21, $22:=$23, $24:=$25\\n\\n#Function call\\n$1($2:=$3, $4:=$5, $6:=$7, $8:=$9, $10:=$11, $12:=$13, $14:=$15, $16:=$17, $18:=$19, $20:=$21, $20:=$21, $22:=$23, $24:=$25)\\n\\n#Recursive Sub call\\n$1 $2:=$2, $4:=$4, $6:=$6, $8:=$8, $10:=$10, $12:=$12, $14:=$14, $16:=$16, $18:=$18, $20:=$20, $22:=$22, $24:=$24, \\n\\n#Recursive Function call\\n$1($2:=$2, $4:=$4, $6:=$6, $8:=$8, $10:=$10, $12:=$12, $14:=$14, $16:=$16, $18:=$18, $20:=$20, $22:=$22, $24:=$24, )"
# You can manually specify the number of replacements by changing the 4th argument
result = re.sub(regex, subst, test_str, 0, re.MULTILINE | re.DOTALL)
if result:
print (result)
# Note: for Python 2.7 compatibility, use ur"" to prefix the regex and u"" to prefix the test string and substitution.
Please keep in mind that these code samples are automatically generated and are not guaranteed to work. If you find any syntax errors, feel free to submit a bug report. For a full regex reference for Python, please visit: https://docs.python.org/3/library/re.html