Activity › Forums › Adobe After Effects Expressions › Color text set with regex
-
Color text set with regex
Posted by Anton Shushar on March 26, 2019 at 1:50 pmHi, I am trying to color text that is between a number and a coma, something like this 0text, or 2something,
So I’d rather use regex for this(?<=\d)([a-z]+)(?=,)But unfortunately I don’t know how to write the expression right inside Text Animator. Hope you could help me with that.Oleg Pirogov replied 7 years, 3 months ago 2 Members · 14 Replies -
14 Replies
-
Oleg Pirogov
March 28, 2019 at 10:53 amFirst of all lookbehind assertion is not implemented in JS before ECMAScript 2018, thus will not work with AE’s legacy expression engine, i.e. will not work in any version before CC 2019. So I will proceed with:
/\d[a-z]+(?=,)/g
, keeping in mind that it also matches the number at the beginning.Next, for picking the desired characters I will use Expression Selector for Text Animator. It runs its expression for every character indexed as “textIndex” if Based On property = Characters. Note, that for the first char textIndex=1 not 0;
For each textIndex expression evaluates, if the corresponding char is one of those to be colored. And colors it if yes.
Looks like this:
var t = text.sourceText;
var regex = /\d[a-z]+(?=,)/g;function indexMatched(index){
var matched = false;
var match;
var i=[];while ((match = regex.exec(t)) !== null){
matched |= match.indexWorks like this:

I hope I got it right and that's what you wish for. -
Oleg Pirogov
March 28, 2019 at 10:55 am“i” stuff was a debugging thing, you don’t need it:
var t = text.sourceText;
var regex = /\d[a-z]+(?=,)/g;function indexMatched(index){
var matched = false;
var match;while ((match = regex.exec(t)) !== null){
matched |= match.index -
Anton Shushar
March 31, 2019 at 10:52 amThank you master, it saved me tons of time! You are the only person who managed to think of the solution.
I have one more little question: how do I animate this color appearing? Range Selector doesn’t work.
-
Oleg Pirogov
March 31, 2019 at 12:28 pmYou’re welcome!
If you mean appearing from left to right or smth like that, just add a Range Selector before Expression Selector and change the last line to:
indexMatched(textIndex-1) ? 100*selectorValue : 0;If you by appearing you mean gradually coloring, you can add a Slider Control to control the transition from 0 to 100% and change the last line to:
indexMatched(textIndex-1) ? effect("Slider Control")("Slider"): 0; -
Anton Shushar
March 31, 2019 at 12:33 pmThank you so much! I am also wondering whether you have issues with previewing it? It just proccess like 30 sec per frame. What can I do with such a delay?
-
Oleg Pirogov
April 1, 2019 at 5:28 amThe code runs for each character each frame. If your text is huge, it might be the cause of your issue.
I suggest forming an array of indices of to-be-colored chars and keeping it a separate layer. This way you at least won’t have to run regex and the while cycle every time. -
Anton Shushar
April 1, 2019 at 4:37 pmI didn’t really get this line:
I suggest forming an array of indices of to-be-colored chars
Coould you explain a bit clearly?
Btw, besides color I’m gonna animate the scale of those words so breaking up the text will lead to kerning issues. -
Oleg Pirogov
April 2, 2019 at 1:44 amMake a separate technical text layer (“Array”) and apply this expression to sourceText:
var txt =thisComp.layer("Text").text.sourceText;
var regex = /\d[a-z]+(?=,)/g;function indexMatched(ind){
var matched = false;
var match;while ((match = regex.exec(txt)) !== null){
matched |= match.index
("Text" is the original text layer)Now its sourceText is smth like "0,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,1,0", each number representing a char in original text, 1=color, 0=not-to-color.
Make the "Array"'s duration 1 frame and convert expression to keyframes, so you can copy that "0,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,1,0".Next, change the expression in "Text" layer for the Expression Selector simply to:
arr = [0,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,1,0];
arr[textIndex-1] ? 100*selectorValue : 0;This will result in the same coloring as before but with less computations. Of cause, this workaround doesn't work, if "Text"'s sourceText changes in time.
BTW, all of these work well only for one-line texts, cause this code doesn't account for the fact that Selector doesn't count carriage return as a character, so coloring gets shifted by the number of lines. But I'm sure, there's some easy workaround for that.
-
Anton Shushar
April 2, 2019 at 4:45 amI tried to make exactly what you’ve said, but for some reasons no text generates in “Array”(it remains empty). However, if I make a copy of the original “Text” and apply the expresion, this error appears:
After Effects warning: Expression Disabled. Error at line 0 in property 'Amount' of layer 2 ('Array') in comp 'Comp 1'.
expression result must be of dimension 3, not 58
BTW, I double-checked that original text layer has name of “Text”. -
Anton Shushar
April 2, 2019 at 11:41 amI just realised that I was setting that expression into “Array”‘s Expresion Selector, not sourceText.
Thanks, it makes almost what I want. But there is one thing that bother me — when I add scale property besides color, kerning doesn’t change, I mean that those regex-filtered words are intersecting neighbour letters, instead of extending space. Is there a workaround?
Reply to this Discussion! Login or Sign Up