1

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.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • What exactly are you trying to match here, or what output do you expect from that code snippet? – Tim Biegeleisen Feb 09 '22 at 08:33
  • 1
    The `\bcatch\s*\([^()]*\).*\.stack\b` or `(?s)\bcatch\s*\([^()]*\).*\.stack\b` [pattern is close](https://regex101.com/r/wldJjD/2) to what you are trying to do here, but parsing code with regex is fraught with many potential problems. – Wiktor Stribiżew Feb 09 '22 at 08:35
  • What I need is to test if it has a pattern that has "catch(anything)" and the further part of this contains a "anything.stack" in the { } bracket. – Bharat Pippal Feb 09 '22 at 09:17

2 Answers2

0

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.

Peter Krebs
  • 3,831
  • 2
  • 15
  • 29
0

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

hc_dev
  • 8,389
  • 1
  • 26
  • 38