0

I've looked and looked and tried it myself many times but I'm failing miserebly. Here is a problem. Say I have a line of JS code that looks like this:

var someVar = myValue; object.subobject.function(with, some = obj.func(a, b[2][1]), arguments); return true;

I'm developing code hints that should show the definition of the function that I keep in a separate file. To get the definition I need to get the name of the function - in this case just the word function

I already have the code that splits the line into two parts: Left (left of the caret) and Right (right of the caret). They I plan to parse those with RegEx and combine them to get the full function call.

If the caret is anywhere before the word function i should get nothing. If it is anywhere after the ) after the word arguments i should get nothing. if the caret is anywhere within those boudaries I sould get the word function - that is the end result I'm after.

However... since I'm splitting the text into left and right parts (needed in case there are more valid function calls in one like and the other function call is not a parameter within some other function call) here are potential Left and Right parts (top and bottom before the //or) of the string being processed (always just one line) by RegEx:

var someVar = myValue; object.subob
ject.function(with, some = obj.func(a, b[2][1]), arguments); return true;
// or
var someVar = myValue; object.subobject.function(with, some = obj.fu
nc(a, b[2][1]), arguments); return true;
// or
var someVar = myValue; object.subobject.funct
ion(with, some = obj.func(a, b[2][1]), arguments); return true;
// and so on

In the two last cases, after the RegEx is done i should have the Left and Right to be equal function(with, some = obj.fu and nc(a, b[2][1]), arguments), or funct and ion(with, some = obj.func(a, b[2][1]), arguments)

Then my plan is to combine the Left and Right to produce function(with, some = obj.func(a, b[2][1]), arguments) which I will then check with another RegEx to see if it's a valid function call, and if it is process it with another to get the word before the (.

I could really use some assistance for developing the RegEx for Left and Right... the rest I have already made. I'm developing this in AutoHotkey to process JavaScript code. Don't even ask me why...

maltaannon
  • 11
  • 1
  • It's possible you are using a screw driver when a hammer would do better. That is, you're trying to parse javascript, so instead of using a regex, you might consider using a parser. There are plenty of JS parsers. JSLint has one: https://stackoverflow.com/a/2630085/751484 – Jonathan M Apr 03 '18 at 20:55
  • Which function are you trying to get the name of? – Nick Apr 04 '18 at 23:40

1 Answers1

0

Maybe some pattern like that can help you:

(?<func>[a-zA-Z_\$]\w+)\s*(\((?>[^()]+|(?2))*\))

Demo


Last call. If a dot and space is good enough as an anchor to identify the start of the function name and the start of the an (optional) object in your code block, you can try this:

(?<obj>[a-zA-Z_$][\w.\n]+\.)?(?<func>[a-zA-Z_$][^. ]+)\s*(?<args>\((?:(?:[^()]+)|(?3))*\))

Update
* Look out: I've changed the flags too.

wp78de
  • 18,207
  • 7
  • 43
  • 71
  • I tried to define the allowed characters for JavaScript function names in a simple and meaningful way. However, JS allows pretty fuzzy names: https://stackoverflow.com/questions/1661197/what-characters-are-valid-for-javascript-variable-names – wp78de Apr 03 '18 at 21:21
  • Wow. This almost works. This is almost perfect. It's exactly what is needed to find just the function name, but I am forced to think of this as "left hand side" and "right hand side" based on the position of the caret (which is the place I split the string). The string is ALWAYS just one line. Just consider that any part (left or right) can be any part of a valid function call. This is sooooooo close. So think of having a two separate RegEx... one for left hand side of any part, one valid for any part of right hand side. – maltaannon Apr 03 '18 at 22:22
  • Just to make sure.... I split the string into Left and Right hand side because it is possible to have multiple function calls in one line. – maltaannon Apr 03 '18 at 22:29
  • @maltaannon I don't think this can be done as described in your comment. The problem is: How to balance (nested) parentheses that are opened or closed out of sight, i.e. on another line?! The regex I've suggest can capture multiple functions on one line (also with nested brackets, try it). So, maybe you want to extract the function definitions first and then split them. Actually, you would have the same problem with a parser. – wp78de Apr 03 '18 at 23:58
  • Ah. I think I misrepresented what the sample was. The line I'm processing is always just one line. In that like however there can be many calls to different functions. That is why I split the line into the Left of the caret (blinking text cursor) position and Right of caret. Those are those two lines separated by "// or" in my question. Top is Left, bottom is Right. After the code sample i've put expected results for both Left and Right in **bold**. With all I know it should be possible, however I'm just to weak with regex and I get confused quickly. – maltaannon Apr 04 '18 at 07:34
  • Just to make sure... line brakes in that large block of code represent where the caret is and how the line of text (always just one line) is being split into Left (top) and Right (bottom). – maltaannon Apr 04 '18 at 08:04
  • 1
    @maltaannon regarding my latest suggestion, what exactly is not working for you? – wp78de Apr 06 '18 at 05:03