Hot answers tagged

20

Currently Twig uses regular expressions only with Comparisons: {% if string matches '{^[\d\.]+$}' %} Do Stuff {% endif %} Craft itself currently doesn't have any custom Twig filters or functions either. But there are third-party plugins which might help you: Twig PCRE Filters Low Regex


7

I think you are getting the twig replace filter (which does not have the regex capability) instead of the Craft replace filter (which does). So this is a bug in Craft, in that their filter is masked by the twig one. You could use the trim filter to remove trailing /s: website|replace({'http://':''})|trim('/') Or you could use one of Victor's Twig PCRE ...


7

Yes. {{ 'this is a string'|replace('/this is a (string)/', 'This is another $1') }} will output This is another string When you pass something that looks like a regex into the |replace filter, preg_replace() is called behind the scenes, so |replace can do anything preg_replace() can do.


6

Brad nails the problem in his comment: The error is because you've got two named subpatterns with the same name (<slug>) And the solution is simple... Change the name(s) of your subpattern(s). The term slug is just a convention of Craft. It doesn't matter what the names are, they can be anything useful to you: (?P<domain>[^/]+)/(?P<...


6

Nope, because MySQL doesn't support RegEx replacements in SQL statements. It's been an open feature request since 2007, so feel free to add your vote. There are some potential workarounds listed here, too.


5

This works for me just fine: {# Removes all characters other than numbers and + #} {{ profile.phone|replace('/[^0-9+]/', '') }}


4

Try doubling-up your backslashes: https://craftcms.com/docs/templating/filters#replace


3

It sounds like you might be trying to blend Craft/Yii routing with Rewrites (if you're coming from an Apache background). I believe what Craft interprets this as is an attempt to map a request to locations/or/my-entry-slug to the <slug> (literal) action of the locations controller (which doesn't exist). If you just want to render a template for these ...


3

Twig auto-escapes the \ character so by the time it makes it to the Craft replace filter PHP code, the regex string looks like /^d+.s/. By double escaping it, you're forcing the correct regex to make it through /^\d+\.\s/.


3

UPDATE: As of Craft v2.2, the replace filter now supports regex: The replace filter now supports regular expressions, by setting the first argument to a string that begins and ends with forward slashes, e.g. '/foo/'. So this should work by adding forward slashes. {% set bar = '/%20AND%20foo%3A%22(.+?)%22/' %} I think this is particular to Craft and not ...


2

Okay, so, thanks to carlcs' answer I managed to solve the camel-case to lower-dash-case conversion. The other direction was a bit trickier, but again, after digging in a bit deeper I was able to figure it out myself: First off, I'm not using the plugin any longer! Yay! The secret was to create a custom Twig filter that would convert dash-separated strings ...


2

An easy fix could be to define an additional route without the offset parameter: return array( 'articles/(?P<sectionId>\d+)' => 'articles/index', 'articles/(?P<sectionId>\d+)/(?P<offset>\d+)' => 'articles/index', ); In your template, you'd need to check if the offset parameter is defined, and if not, set it to 0: {{ offset |...


2

The plugin probably uses PHP's json_encode to serialize the data and it automatically escapes quotation marks and backslashes to conform to the JSON format. Escaping the forward slashes of your URL wouldn't actually be necessary, but I just found this on StackOverflow which might give an idea why the function escapes them anyways: https://stackoverflow.com/...


2

Craft's replace filter only supports doing multiple strings replacements at once. If you want to do a regex replacement, it will have to be it's own separate call. In your case, you'd have to do something like this: {% set url = "http://www.google.com/"|replace('http://', '') %} {{ url|replace('/\\/$/', '') }}


2

The RegEx is only the URI part; so something like (.*.png|.*.jpg) is probably what you want.


2

You were close! Just don't use the Twig hash/array syntax when using the |replace filter if you want Craft to process it as regex. This should do what you're looking for: {% set svg_image_output = svg_image|replace('/#[a-zA-Z0-9]{6}|rgb\\((?:\\s*\\d+\\s*,){2}\\s*[\\d]+\\)|rgba\\((\\s*\\d+\\s*,){3}[\\d\\.]+\\)|hsl\\(\\s*\\d+\\s*(\\s*\\,\\s*\\d+\\%){2}\\)|...


2

Doh! It was my ternary logic that was failing not the regex. I’m now doing this: {% set vidUrl = block.videoUrl %} {% if 'youtu' in vidUrl %} {# Check for an 'embed' URL which may need cleaning #} {% set vidId = 'embed' in vidUrl ? vidUrl|replace('/^http.*embed\\/([^\\?]+)(\\?.*)?$/', '$1') : null %} {# Check for a 'watch' URL which may need ...


2

Here's the regex I think you'll need: \/teachings\/tag\/\d+\/(\w+)\/? → \/teachings\/topics\/$1 \/teachings\/series\/\d+\/(\w+)\/? → \/teachings\/series\/$1 A couple explanations: \/ is an escaped / character \d+ means one or more digit (0-9) \w+ means one or more alphanumeric/underscore character (A-Z, a-z, 0-9, _) surrounding something in parentheses ...


1

There are a couple of existing plugins that look like they might do what you're looking for: https://plugins.craftcms.com/password-policy https://plugins.craftcms.com/enforce-password And of course, you could always write a plugin that meets your exact requirements as well.


1

You'll need to double escape those backslashes in the regex. {% set ig = user.instagram|raw|replace('/(?:(?:http|https):\\/\\/)?(?:www.)?(?:instagram.com|instagr.am)\\/([A-Za-z0-9-_\\.]+)/im') %}


1

Actually, excluding certain tags from being removed is built into the striptags filter. You can use it like this: {{ articleTextTrim | striptags('<a>') }}


1

Something like this should work: {{ snippet|replace('/<img([\w\W]+?)>/', '') }} You can see an explanation of the regex in the right column of https://regex101.com/r/DvJHeY/1


1

A workaround in light of my comments on Brandon’s reply… If I ignore the attempt to act on child tags only, I can search for opening tags of all generated elements (regardless of whether they are nested) with… {% set elems = elems|replace('/(<[a-z][a-z0-9]*\\b[^>]*>)/', '$1>,') %} and then… {# Convert elems to an array #} {% set elems = ...


1

Backreferences within the regex are normally defined as \1, \2, etc. In the |replace filter you need to escape all backslashes, so it’ll be \\1, \\2, etc.


1

Is it simply not possible to use backrefs in the target route templates Right now it's not possible (although might be worth a feature request). The right hand side of the route key => value pair can currently only be a static string that is a path to the template to load or an array that defines a controller action to load.


1

I'm not sure what's going on with the story.html part, but you'll need to double escape your regex. Assuming you have an entry already with a story Rich Text field, it'd look like this: {{ entry.body|raw|replace("/<p>\\s*(<a .*>)?\\s*(<img .* \\/>)\\s*(<\\/a>)?\\s*<\\/p>/iU", "\1\2\3") }}


1

You could add this to the homepage template. {% if craft.request.getParam('post_type') == "testimonials" %} {% redirect "/about-us" %} {% endif %}


1

Can't help you with that \e modifier problem and my regex knowledge is very limited, but that camelCase problem can be solved with Twig filters: {{ 'camelCase'|replace('/([A-Z])/', '-\\1')|lower }}


1

I'll add my two cents here, since it appears you are removing Wordpress created images (which I also did). I wrote a regex initially to find all these duplicated files (this command works specifically on OSX, but is pretty portable): find -E . -regex '.*\-[0-9]{1,4}\x[0-9]{1,4}\.(png|gif|jpg)$' I then wrote a minor change to delete them: find -E . -regex ...


Only top voted, non community-wiki answers of a minimum length are eligible