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

Multiple Line Replace Script?

Participant ,
Dec 06, 2017 Dec 06, 2017

I've been trying to modify this script to ignore case (so it works with uppercase and lowercase) as well as work when there are line breaks between words. Often some of the longer terms have a line break between them such as:

Arabian

Desert

And I want to still replace the term with my target language (with no line break would be fine).

I've tried modifying the script to work with RegEx but I can't get it to work. Any help would be greatly appreciated.

function FindAndReplaceScript_AllOpenDocuments(){       

 

 

    for(var i=app.documents.length -1; i > -1;  i--){       

        app.documents.activate();   

        var aDoc = app.documents;   

 

//List of words to replace 

        var mapObj = { 

            "Damascus":"ដាម៉ាស", 

            "Rabbah":"រ៉ាបាត", 

            "Samaria": "សាម៉ារី",

            "Arabian Desert": "ទីរហោស្ថានអារ៉ាប់"

            };         

               

        var theTF = aDoc.textFrames;       

        if (theTF.length > 0) {       

            for (var j = 0 ; j <theTF.length; j++) {       

                var aTF = theTF;      

                for (var re in mapObj) { 

                var newString = aTF.contents.replace(re, mapObj[re]) 

                if (newString != aTF.contents) {       

                    theTF.contents = newString;       

                }       

            }    

  } 

        }   

    }   

};       

FindAndReplaceScript_AllOpenDocuments();    

TOPICS
Scripting
2.6K
Translate
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

correct answers 1 Correct answer

Community Expert , Dec 11, 2017 Dec 11, 2017

Unfortunately that is not so easy.

I rarely work with object-objects in [JS]

I don't know how to change the keys in object (wordlist). Only that's why I use this cumbersome workaround with a second object.

Hope this helps a little:

// https://forums.adobe.com/message/10023166#10023166

FindAndReplaceScript_AllOpenDocuments ();

function FindAndReplaceScript_AllOpenDocuments () {

for(var i=app.documents.length -1; i > -1;  i--) {

    app.documents.activate();

    var aDoc = app.documents;

    //List of words

...
Translate
Adobe
Valorous Hero ,
Dec 06, 2017 Dec 06, 2017

You may have to use the reg exps to solve this problem.

aTF.contents.replace(new RegExp(re.replace(" ", "[\r\n\s\t]"), "ig"), mapObj[re])

In this attempt, a new RegExp is formed to be the argument for your contents.replace().

A new RegExpt takes arguments of a string-version of a regular expression as well as a string of flags. "ig" has "i" for ignore case and "g" for global.
The arguments to the RegExp have the 'search string' variable with replaced spaces by a regular expression character collection: Arabian[\r\n\s\t]Desert

The idea is to match "Arabian Desert" in the contents with possibility of a single (\r) carriage return, (\n) soft-return, (\s) a space, and (\t) a tab. Hopefully this will work and match the strings as desired!

Translate
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
Participant ,
Dec 06, 2017 Dec 06, 2017

Silly-V wrote

You may have to use the reg exps to solve this problem.

aTF.contents.replace(new RegExp(re.replace(" ", "[\r\n\s\t]"), "ig"), mapObj[re])

In this attempt, a new RegExp is formed to be the argument for your contents.replace().

A new RegExpt takes arguments of a string-version of a regular expression as well as a string of flags. "ig" has "i" for ignore case and "g" for global.
The arguments to the RegExp have the 'search string' variable with replaced spaces by a regular expression character collection: Arabian[\r\n\s\t]Desert

The idea is to match "Arabian Desert" in the contents with possibility of a single (\r) carriage return, (\n) soft-return, (\s) a space, and (\t) a tab. Hopefully this will work and match the strings as desired!

Thanks - this is getting closer.

But it I just realized there are sometimes three spaces in terms like this:
Sea ofGalilee

I tried to modify the script like this (placing the \s in the search term instead of in the RegEx):

function FindAndReplaceScript_AllOpenDocuments(){    

    for(var i=app.documents.length -1; i > -1;  i--){    

        app.documents.activate();

        var aDoc = app.documents;

//List of words to replace

        var mapObj = {

"Sea\sof\sGalilee":"សមុទ្រកាលីឡេ",

"Bethel":"បេត-អែល"

            };      

            

        var theTF = aDoc.textFrames;    

        if (theTF.length > 0) {    

            for (var j = 0 ; j <theTF.length; j++) {    

                var aTF = theTF;    

                for (var re in mapObj) {

                var newString = aTF.contents.replace(new RegExp(re.replace(" "), "i"), mapObj[re])

                if (newString != aTF.contents) {    

                    theTF.contents = newString;    

                }    

            }  

  }

        }

    }

};    

FindAndReplaceScript_AllOpenDocuments();

But it still doesn't find the term. I'll keep working on it. Any ideas?

Translate
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 ,
Dec 06, 2017 Dec 06, 2017

How about this, change:

new RegExp(re.replace(" ", "[\r\n\s\t]")

To

new RegExp(re.replace(/\s/g, "[\r\n\s\t]")

Translate
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
Participant ,
Dec 06, 2017 Dec 06, 2017

Still doesn't work...very strange. And now it isn't even replacing terms with one space (like "Dead Sea").

Translate
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 ,
Dec 06, 2017 Dec 06, 2017

Okay, with my latest suggestion, can you try with escaping the backlashes:

var rx = new RegExp(str.replace(/\s/g, "[\\r\\n\\s\\t]"), "gi");

Translate
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
Participant ,
Dec 06, 2017 Dec 06, 2017

That worked!

Thank you so much @Silly-V!

Translate
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 ,
Dec 06, 2017 Dec 06, 2017

Hi Silly-V,

you are near.

Be sure in regex \r \n and \t is included in \s

But sometimes Illustrator scripting don't like \n

Try to avoid this line break in your documents.

That's why you only need

function FindAndReplaceScript_AllOpenDocuments() {

    for(var i=app.documents.length -1; i > -1;  i--) {

        app.documents.activate();

        var aDoc = app.documents;

        //List of words to replace

        var mapObj = {

            "Lorem ipsum dolor":"TEXT#1",

            "consectetuer adipiscing elit":"TEXT#2",

            "sed diam nonummy":"TEXT#3",

        };

        var theTF = aDoc.textFrames;

        if (theTF.length > 0) {

        for (var j = 0 ; j <theTF.length; j++) {

            var aTF = theTF;

            for (var re in mapObj) {

                var newString = aTF.contents.replace(new RegExp(re.replace(/ /g, "[\\s]"), "gi"), mapObj[re]);

                if (newString != aTF.contents) {

                    theTF.contents = newString;

                    }

                }

            }

        }

    }

};

FindAndReplaceScript_AllOpenDocuments();

Your regex knowledgebase will be better and better.

Have fun

Translate
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
Participant ,
Dec 10, 2017 Dec 10, 2017

One more question. How would I go about changing the regex to only match whole words? Currently it will find "ur" in "captured" and replace the ur with Khmer (I'm working on maps of the Ancient Near East): captអ៊ើរed

But I'd rather it let partial matches go and only replace whole words. Is that possible?

Translate
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 ,
Dec 11, 2017 Dec 11, 2017

Would making it case-sensitive solve this?

Translate
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
Participant ,
Dec 11, 2017 Dec 11, 2017

The problem is sometimes some terms are all caps (like ARABIAN DESERT and Arabian Desert) and I want to replace both (my target language has no capitalization so I replace the same term both times regardless). Any way around that?

Translate
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 ,
Dec 11, 2017 Dec 11, 2017

Okay, I will use the site regexpal.com to test additions to our regular expression. Can you, say, provide me a sample paragraph which contains one of these problematic word scenarios?

Translate
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
Participant ,
Dec 11, 2017 Dec 11, 2017

Yeah, I can get it to work in a non-illustrator environment see here https://regex101.com/r/Ly13ZO/1 

The issue is I can't figure out how to use \b in the script...

Translate
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 ,
Dec 11, 2017 Dec 11, 2017

Please show us your

List of words to replace

  1.         //List of words to replace 
  2.         var mapObj = { 
  3.             "Lorem ipsum dolor":"TEXT#1"
  4.             "consectetuer adipiscing elit":"TEXT#2"
  5.             "sed diam nonummy":"TEXT#3"
  6.         };

We need exact examples.

Translate
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
Participant ,
Dec 11, 2017 Dec 11, 2017

Sure, here's the script as I have it now (with some words redacted as the list is very long):

function FindAndReplaceScript_AllOpenDocuments(){      

    for(var i=app.documents.length -1; i > -1;  i--){      

        app.documents.activate();  

        var aDoc = app.documents;  

//List of words to replace

        var mapObj = {

"Arabian Desert":"ទីរហោស្ថាន​អារ៉ាប់",

"Damascus":"ដាម៉ាស",

"Dead Sea":"សមុទ្រ​ស្លាប់",

"On":"អូ ",

"Ur":"អ៊ើរ"

            };        

              

        var theTF = aDoc.textFrames;      

        if (theTF.length > 0) {      

            for (var j = 0 ; j <theTF.length; j++) {      

                var aTF = theTF;    

                for (var re in mapObj) {

                var newString = aTF.contents.replace(new RegExp(re.replace(/ /g, "[\\s]"), "gi"), mapObj[re]);

                //var newString = aTF.contents.replace(re, mapObj[re])  

                if (newString != aTF.contents) {      

                    theTF.contents = newString;      

                }      

            }  

  }

        }  

    }

};      

FindAndReplaceScript_AllOpenDocuments();

Then make a document with this text:

ARABIAN DESERT

Arabian Desert

Captured

UR

ur

Ur

deception

The desired result would be that "Captured" and "deception" would be left alone, while the others would be replaced.

I've tried adding a word boundary \b but can't get it to work in the regex code in Illustrator. I can get it to work in plain regex though.

Translate
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
Participant ,
Dec 11, 2017 Dec 11, 2017

I've tried this, but I can't seem to get InDesign to understand \b (and probably because I don't understand!).

RegExp(re.replace(/\b[ ]\b/g, "[\\s]"), "gi"), mapObj[re]);

Translate
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 ,
Dec 11, 2017 Dec 11, 2017

Unfortunately that is not so easy.

I rarely work with object-objects in [JS]

I don't know how to change the keys in object (wordlist). Only that's why I use this cumbersome workaround with a second object.

Hope this helps a little:

// https://forums.adobe.com/message/10023166#10023166

FindAndReplaceScript_AllOpenDocuments ();

function FindAndReplaceScript_AllOpenDocuments () {

for(var i=app.documents.length -1; i > -1;  i--) {

    app.documents.activate();

    var aDoc = app.documents;

    //List of words to replace

    /*

    var mapObj = {

        "Arabian Desert":"ទីរហោស្ថានអារ៉ាប់",

        "Damascus":"ដាម៉ាស",

        "Dead Sea":"សមុទ្រស្លាប់",

        "On":"អូ ",

        "Ur":"អ៊ើរ"

    };

    */

    var mapObj = {

        "Arabian Desert":"AD_replaced_AD",

        "Damascus":"D_replaced_D",

        "Dead Sea":"DS_replaced_DS",

        "On":"O_replaced_O ",

        "Ur":"U_replaced_U"

    };

    var mapObj2 ={};

    mapObj2 = createObjBasedOnFirstObj (mapObj, mapObj2);

    var theTF = aDoc.textFrames;

    if (theTF.length > 0) {

        for (var j = 0 ; j <theTF.length; j++) {

            var aTF = theTF;

            //for (var re in mapObj) {

            for (var re in mapObj2) {

                //var newString = aTF.contents.replace(new RegExp(re.replace(/ /g, "[\\s]"), "gi"), mapObj2[re]);

                var newString = aTF.contents.replace(new RegExp(re, "gi"), mapObj2[re]);

                if (newString != aTF.contents) {

                    theTF.contents = newString;

                    }

                }

            }

        }

    }

};

function createObjBasedOnFirstObj (obj1, obj2) {

// regards pixxxel schubser

for (var re0 in obj1 /*mapObj*/) {

    var re1 = re0.split(' ');

    for (k = 0; k <re1.length; k++) {

        re1 = "\\b"+re1+"\\b";

        }

    re1 = re1.join("\\s");

    obj2[re1] = obj1[re0];

    }

return obj2;

};

Have fun

Translate
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
Participant ,
Dec 11, 2017 Dec 11, 2017
LATEST

Thanks! That does the trick. Funny how complex it has to be But now everything is working great!

Translate
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