Velocity: Regex capturing groups | Community
Skip to main content
New Participant
July 22, 2021
Solved

Velocity: Regex capturing groups

  • July 22, 2021
  • 1 reply
  • 9542 views

I was wondering if there's a possibility in velocity to use regex capturing groups? So, as a simple example, we may want to get "Some Name", "13:00" and "14:00" from the following input string: "Some Name: 13:00 - 14:00".

 

There are multiple ways how this can be achieved but one possibility would be to use a simple regex such as "^(.+):\s?(\d{1,2}:\d{1,2})\s?\-\s?(\d{1,2}:\d{1,2})$" and then extract the parts from the three capturing groups.

 

Something like "matches" in Velocity only returns a Boolean which can be used to e.g. compare a input to a pattern.

 

#set( $input = "Some Name: 13:00 - 14:00" ) #set( $regex = "^(.+):\s?(\d{1,2}:\d{1,2})\s?\-\s?(\d{1,2}:\d{1,2})$" ) #if ( $input.matches($regex) ) ## We have a match #end

 

 

In JavaScript land you could e.g. do something simple such as

 

const [_, name, timeFrom, timeTo] = "Some Name: 13:00 - 14:00".match(/^(.+):\s?(\d{1,2}:\d{1,2})\s?\-\s?(\d{1,2}:\d{1,2})$/i) || [];

 

Is there something similar in Velocity? Given the example above, we could "split" by multiple delimiters or use multiple "replace" runs to get the parts but that obviously has its limitations and feels somewhat hacky.

Maybe @sanfordwhiteman has an idea? Thanks in advance.

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.
Best answer by SanfordWhiteman

It's not so much capturing groups you're lacking (which are supported) it's an iterable set of match results.

 

In Marketo's Velocity, you can't create a Matcher object (other Velocity installs do support this). 

 

The closest way to simulate would be replaceAll and put a known-unused delimiter - like the ASCII record delimiter in the below example - then split on the delimiter.

#set( $input = "Some Name: 13:00 - 14:00" ) #set( $regex = "^(.+):\s?(\d{1,2}:\d{1,2})\s?\-\s?(\d{1,2}:\d{1,2})$" ) #set( $output = $input.replaceAll( $regex, "$1\u001e$2\u001e$3" ).split("\u001e") ) #foreach( $part in $output ) ${part} #end

 

Figure I'll do a blog post on this one of these days.

1 reply

SanfordWhiteman
SanfordWhitemanAccepted solution
New Participant
July 22, 2021

It's not so much capturing groups you're lacking (which are supported) it's an iterable set of match results.

 

In Marketo's Velocity, you can't create a Matcher object (other Velocity installs do support this). 

 

The closest way to simulate would be replaceAll and put a known-unused delimiter - like the ASCII record delimiter in the below example - then split on the delimiter.

#set( $input = "Some Name: 13:00 - 14:00" ) #set( $regex = "^(.+):\s?(\d{1,2}:\d{1,2})\s?\-\s?(\d{1,2}:\d{1,2})$" ) #set( $output = $input.replaceAll( $regex, "$1\u001e$2\u001e$3" ).split("\u001e") ) #foreach( $part in $output ) ${part} #end

 

Figure I'll do a blog post on this one of these days.

MarkusBiAuthor
New Participant
July 23, 2021

Great, thanks, that's what I was looking for.