• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Select part of point text objects matching a regex expression

Explorer ,
Feb 10, 2017 Feb 10, 2017

Copy link to clipboard

Copied

Hello! I'm looking for a way to run through a bunch of point text objects and select part of the string in each text object based on a regex expression. I found this awesome script that can do a regex find/replace, but my end goal is not to replace, but to apply a given character style to part of the string.

For example, I have two point text objects:

first / second / third

one / two / three

And I want to be able to select "/ second /" and "/ two /" to be able to apply a different character style to that part of each point text object. Also, i'm not sure that you can have parts of two different point text objects selected at the same time, so the script might need to apply the active text style to the matched string parts as it passes through them.

Is this impossible?

Thanks!

TOPICS
Scripting

Views

2.5K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe
Community Expert ,
Feb 10, 2017 Feb 10, 2017

Copy link to clipboard

Copied

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Feb 15, 2017 Feb 15, 2017

Copy link to clipboard

Copied

Wow! I think that might be the ticket. I'm not having luck making it work though. I think it must be that my regex is incorrect. I'm wondering if you could shed any light on what I'm doing wrong.

#target illustrator

function test(){

// regex_changeContentsOfWordOrString_RemainFormatting.jsx

// regards pixxxel schubser

var doc = app.activeDocument;

var s = new RegExp("[0-9]*$","gi");

var myStyle = doc.characterStyles.getByName("MyStyle");

var atf = activeDocument.textFrames[0];

while (result = s.exec(atf.contents)) {

    try {

        aCon = atf.characters[result.index];

        aCon.length = result[0].length;

        myStyle.applyTo(aCon);

        } catch (e) {};

    }

};

test();

assuming

-I have a character Style setup named "MyStyle"

-I have two point text objects:

            "one / 334 / three"

            "first / 563 / third"

-I have the point text objects selected (or un-selected?)

when I run the script it should set "334" and "563" from whatever the style was to 'MyStyle', correct? The script appears to run correctly without any errors, but does not make the character style change. If I don't have 'MyStyle' setup, i get an error reporting that.

Thank you!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Feb 15, 2017 Feb 15, 2017

Copy link to clipboard

Copied

Use this site to test your Regex:Regex Tester - Javascript, PCRE, PHP

You will see that your expression "matches 0 characters and therefore matches infinity".

If you only want 3 numbers in a row, you can try this: \d{3}

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Feb 15, 2017 Feb 15, 2017

Copy link to clipboard

Copied

Thank you! I'm new to regular expressions and am just getting the hang of them. I replaced that bit with the one you provided, and it works in the Regex Tester, but still isn't changing the character style in Illustrator:

#target illustrator

function test(){

// regex_changeContentsOfWordOrString_RemainFormatting.jsx

// regards pixxxel schubser

var doc = app.activeDocument;

var s = new RegExp("\d{3}","gi");

var myStyle = doc.characterStyles.getByName("MyStyle");

var atf = activeDocument.textFrames[0];

while (result = s.exec(atf.contents)) {

    try {

        aCon = atf.characters[result.index];

        aCon.length = result[0].length;

        myStyle.applyTo(aCon);

        } catch (e) {};

    }

};

test();

Doesn't work to change the character style on point text objects containing the following strings:

first / 563 / third

one / 334 / three

334

563

Maybe, i'm messing up with how I have them selected, or organized in layers?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Feb 15, 2017 Feb 15, 2017

Copy link to clipboard

Copied

Oh yea, when you have backslashes (\), they escape things right in front of them when used inside of strings, so if you are making your regexp with the syntax above, you have to put double backslashes so as to escape the 2nd backslash so that you get your digit character fed into the string properly.

Also, you don't have key word var for a few of your variables, which causes them to leak into the global scope and would mess up your tests later on.

I also had to restart my AI because after running the script as you posted, it caused it act goofy and not succeed with the edited script right afterwards.

Try this edited script:

#target illustrator

function test(){

// regex_changeContentsOfWordOrString_RemainFormatting.jsx

// regards pixxxel schubser

var doc = app.activeDocument;

var s = new RegExp("\\d{3}","gi");

var myStyle = doc.characterStyles.getByName("MyStyle");

var atf = activeDocument.textFrames[0];

var result, aCon;

while ( result = s.exec(atf.contents)) {

    try {

        aCon = atf.characters[result.index];

        aCon.length = result[0].length;

        myStyle.applyTo(aCon);

        } catch (e) {};

    }

};

test();

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Feb 15, 2017 Feb 15, 2017

Copy link to clipboard

Copied

Thanks, Silly-V. I so appreciate your help. I'm still not able to make it happen with that most recent version. I restarted illustrator as well. I make a quick screen recording..maybe you can spot what i'm doing wrong? illustrator regex char style - YouTube

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Feb 15, 2017 Feb 15, 2017

Copy link to clipboard

Copied

var atf = activeDocument.textFrames[0]; means that you are targeting the very first text frame in your document.

If your very first text frame doesn't have the 3 digits, it will work by not finding any matches and not performing any work therefore.

To help you get an insight into what's happening - as you're starting to script, it is essential to use the Extendscript Toolkit and to use the breakpoints along with its Data Browser panel. This way you can step through your code and see exactly what's happening.

For example, you'd be able to see the contents of the atf variable.

2017-02-15 16_55_15-.png

Without this you're flying blind, so it's real useful.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Feb 15, 2017 Feb 15, 2017

Copy link to clipboard

Copied

That was it! It now works on the first text frame in the document. It's not looping through any other textframes though. Thank you for that description--I'll get this working in Extendscript so I can troubleshoot the loop. Thank you!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 05, 2017 Apr 05, 2017

Copy link to clipboard

Copied

So, I've been struggling with this script for a long time. The code above works great to target a single text frame. I'm trying to get it to loop through all of the textframes in a document. The code below works for more than one textframe, so the loop is sort of working, but it only works for a few and many identical textframes are not getting the character style change. Any ideas why this loop might not be working for all textframes?

The .ai doc (CS6) i've been using is here: Dropbox - regex-test.ai

Thank you!

#target illustrator

function test(){

// regex_changeContentsOfWordOrString_RemainFormatting.jsx

// regards pixxxel schubser

var doc = app.activeDocument;

var s = new RegExp("\\d{3}","gi");

var myStyle = doc.characterStyles.getByName("MyStyle");

for ( i = 0; i < app.activeDocument.textFrames.length; i++ ) {

    var atf = activeDocument.textFrames;

    var result, aCon;

    while ( result = s.exec(atf.contents)) {

        try {

            aCon = atf.characters[result.index];

            aCon.length = result[0].length;

            myStyle.applyTo(aCon);

            } catch (e) {};

        }

}

};

test();

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 15, 2017 Apr 15, 2017

Copy link to clipboard

Copied

In your loop try running it backwards. ie: for ( i = app.activeDocument.textFrames.length; i =>0; i-- )

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 15, 2017 Apr 15, 2017

Copy link to clipboard

Copied

Thanks for looking at this, Larry! When I tried the loop backward, Extendscript didn't like the '=>' and said the '>' does not have a value.

i tried:

for ( i = app.activeDocument.textFrames.length; i >0; i-- )

and then the script ran, but then it's telling me that the 'atf' variable has no value.

If I set 'i' explicitly to the number of text frames in the doc, (For example 7 total textframes in the document) I can get the loop (i--) to apply the style to TF 6 and TF 5, and then with (i++) I can get it to apply the style to TF 0, TF 1, and TF 6, but can't figure out why it's not just going through all of them. If that makes any sense.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 16, 2017 Apr 16, 2017

Copy link to clipboard

Copied

OK, try switching the equals and greater than in the second statement. ( i >= 0 )

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 16, 2017 Apr 16, 2017

Copy link to clipboard

Copied

Hmm, that one is still coming up with 'atf' as 'no such element'

#target illustrator

function test(){

// regex_changeContentsOfWordOrString_RemainFormatting.jsx

// regards pixxxel schubser

var doc = app.activeDocument;

var s = new RegExp("\\d{3}","gi");

var myStyle = doc.characterStyles.getByName("MyStyle");

for ( i = app.activeDocument.textFrames.length; i >=0; i-- ) {

    var atf = activeDocument.textFrames;

    var result, aCon;

    while ( result = s.exec(atf.contents)) {

        try {

            aCon = atf.characters[result.index];

            aCon.length = result[0].length;

            myStyle.applyTo(aCon);

            } catch (e) {};

        }

}

};

test();

Any help is so appreciated! I'm thinking that maybe i'm going about this loop in the wrong way all together..

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Apr 16, 2017 Apr 16, 2017

Copy link to clipboard

Copied

LATEST

Ah, it's got to be in your for-loop. When counting backwards, make sure to subtract 1 from the .length of the array. For example if you had an array of 5 items, it's length would be 5. But the very last item is going to be at index [4].

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines