Switch Node: Pass on regexp matches with the msg

Hi there,

I have this idea .... would it be possible to pass on the matches of a regexp in a switch node?

The groupings in my regexp could be attached to the msg object and then used down the line ... instead of me adding a new change/function node to do the same regexp.

So the msg object would come out with msg.match = [...] or whatever the match object is ....

I know: this does go against the switch node not modifying the msg object but just this once ... plllleeeeeaaaasssssseeeeee!

2 Likes

ooo - like that ! :+1:

2 Likes

Damn ... I was hoping you'd post "check this magic checkbox and it works" ... :frowning:

:wink:

it's an invisible checkbox....

So - having a quick look - of course javascript regex doesn't return a standard object - so would we want to return a non-standard object or re-map it to some other shape.
Also currently we just do a match so it stops on first hit - would need to change it to matchAll and use /g which could have performance impacts I guess.

looking at the screenshot, i see space next to the "ignore case" option ... "add matches to msg" as an extra option so that existing performance is maintained.

So that would be the magic invisible-made-visible checkbox ...

Do you have any standalone examples I could play with ? (so we can looks at possible output format)

$match($$.url,/^https:\/\/github\.com\/([^\/]+)\/([^\/]+)\/blob\/([^\/]+)\/(.+)/)

that parses a github url - https://github.com/gorenje/erlang-red/blob/main/src/nodes/bookkeepers/ered_node_disabled.erl - What I get from that is owner, repo, revision and path - so four parts.

The jsonata result is:

{
  "match":"https://github.com/gorenje/erlang-red/blob/main/src/nodes/bookkeepers/ered_node_disabled.erl",
  "index":0,
  "groups":[
   "gorenje",
   "erlang-red",
   "main",
   "src/nodes/bookkeepers/ered_node_disabled.erl"
  ]
}

so keeping it similar would probably be optimal...

what does jsonata return for multiple matches in a string eg /[b][aio]/g with "bishbashbosh" ? Ie should it really return and array of matches each element of which is like above ?

Let me give an unpopular view...
If you know how to use e a regex and return matches, and/or work with JSONata, you are no longer in low code zone.
Then why not just use a function node with multiple output ports, and do anything you want?

[
  {"match":"bi","index":0,"groups":[]},
  {"match":"ba","index":4,"groups":[]},
  {"match":"bo","index":8,"groups":[]}
]

But a function node is even more knowledge. JSONata is well documented and easier to understand, JavaScript is definitely more complex hence knowing JSONata does not necessarily mean you know how to create JS code.

As for regex, that's just magic that you're either born with or not...

Sure, everything done in a flow can be done with a single function node but then I won't be using Node-RED ... the challenge lies in not using the function node.

In this case, it's about not repeating the regexp in two different places.

Well I guess todays popular view would be just to throw the text at an LLM and ask it to sort it out for you :slight_smile: but yeah - this is just a Friday evening goof off at present. Function nodes is what I do now and :person_shrugging: options.

2 Likes

To each his own weapon, of course, but I beg to differ. JS is widely used, while JSONata is quite obscure to non-node-red users (and also introduces a performance hit on top of, well, JS which is what node-red is written with.

1 Like

Why would it be replicating the regex? You just replace a switch node with a function node.
A function node allows you even better reuse by setting the regex (or logical functions, which are more readable than regex magic) as global/flow context variables.

Make no mistake. I love node-red, and I love visual programming, but I see some people create flows which grow up to become huge & complex, and hard to understand & maintain. They could be simplified with some function nodes.

BTW, function nodes can also (where needed) ensure that multiple actions are executed as one transaction without race conditions between messages.

Being focused on a single language makes everything a nail. I personally am a polyglot programmer: use the right language for the problem, don't make the problem fit into the language one knows.

Being that strange person who decided to replicate Node-RED in Erlang, I use a lot of JSONata because I've ported JSONata to Erlang. Hence I prefer JSONata so that I can copy & paste my Node-RED flows into Erlang-Red and have them execute there - in Erlang.

So JSONata, JS, Erlang or Java, Python, Lisp and Schema ... Prolog or perhaps Bash - what's the difference, as long as the problem gets solved.

Just as an aside, I'm currently working with a large and confusing codebase. I'm trying to identify particularly complicate bits of code, so that they can be refactored. What I have done is began to visual the Abstract Syntax Tree (AST) as flows:

what is shown are the branches of switch/case and if statements but using minified nodes (hence all the same size). That flow is a (part) visualisation of 20k lines of Erlang.

Why? Because I can visual 20k lines of code in a single flow:

(Note: bottom right is a case/switch statement with many branches ... hm?)

Now the fun bit is that this is a flow and I can send messages through this flow - so my representation of Erlang code is Node-RED and is executable. Eventually this NR code will generate the Erlang code again.

That's the kind of stuff I like to do.

2 Likes

Yes but those are the same people that generate complicate text code. Sorry to say but coding requires discipline and reflection and refactoring. If you don't do these things, then visual or textual, the result will be the same.

Hence you don't want state in your flows. Using context (flow, node or global) is an error - the only state is in the message object, therefore there wouldn't be a race condition to take care of.

Race conditions only occur if resources are shared.

For background on this, see Flow-based Programming - Node RED is not flow based programming, it's inspired by FBP.

Node-RED even gets a mention||

Yeah - we had a call with Paul Morrison way back when, after we discovered that we had re-invented FBP, and that he had been at IBM also.

I'm going to quote you on that! My thinking of the lineage had been that Node-RED was influenced by Yahoo! Pipes and FBP but then it's just Yahoo! Pipes or did Nick and you not know of that either :wink:

Speaking of lineage, apparently FBP influenced Unix PIpes - at least there is some discussion around this over at the c2 wiki. But that would then, for me, make a relative clear lineage: NothingnessOfGodlessness --> FBP --> Unix Pipes --> Yahoo! Pipes --> Node-RED which makes great story telling! Of course Paul Morrison was inspired by something and it would be nice to know what.

Can I take that heritage and be somewhat correct?

Why not do the regex using js or JSONata prior to the switch node, then use the switch node to check for matches

Seems adding extra complexity to the switch node is not really required here.

1 Like