So far my regex is ->
myRegex = /catch *\(.\) */
I want to be able to search the following string -
try {
print(new Function (astatement)())
} catch (e) { print(e.stack) }
So that if .stack is present after catch(anything) it should return true, so far I have managed to reach the catch(anything), stuck from here.
CodePudding user response:
Matching for {[^}] }
Matching simple code in the exception handler, provided there are no nested curly braces:
catch *\((\w )\) *{[^}] (\1)(\.stack)[^}] }
The above regular expression matches these examples
(capturing groups for my sake, remove them if not needed):
try {
print(new Function (astatement)())
} catch (e) { print(e.stack) }
try {
print(new Function (bstatement)())
} catch (exception) { print(exception.stack) }
You can try it out here:
https://regex101.com/r/PuytDJ/2
Some techniques used here
\w
Instead of just .
I assume you can give the exception instance any name, so maybe more safe to use \w
here.
{[^}]
This looks for an opening curly brace and catches every non-closing curly brace until the next expression. It works only if you do not have nested curly braces in your exception handler.
(\1)
Here I reference the exception's variable name found in capturing group 1.
(\.stack)
Here is finding .stack
literally
[^}] }
I continue to parse for all non-curly braces characters and finally the closing curly bracket.
Disclaimer
⚠ This being said, regular expressions cannot parse nested elements very well, or only to a certain degree with increasingly more complex expressions.
So code blocks, HTML/XML Tags, JSON objects etc. are better parsed, not text-searched in.
CodePudding user response:
Using a Javascript parser, you can traverse through the syntax-tree (AST) and find each ".stack" inside a catch-block.
For example use slimit
in Python:
from slimit import ast
from slimit.parser import Parser
from slimit.visitors import nodevisitor
data = """
try {
print(new Function(astatement)())
} catch (e) {
print(e.stack)
}
"""
parser = Parser()
tree = parser.parse(data)
def nextCatch(tree):
for node in nodevisitor.visit(tree):
if isinstance(node, ast.Catch):
return node
def nextIdentifierStack(tree):
for node in nodevisitor.visit(tree):
if isinstance(node, ast.Identifier) and node.value == 'stack':
return node
def printChildren(node):
for i, ch in enumerate(node.children()):
print(f"{i:2}: {ch.to_ecma()}")
catch = nextCatch(tree)
printChildren(catch)
stack = nextIdentifierStack(catch)
print(stack.to_ecma())
Prints: the catch block with 2 children and the found stack
identifier
0: e
1: {
print(e.stack);
}
stack
See also JavaScript parser in Python