17 Replies Latest reply on Dec 11, 2017 3:41 PM by nathanwells

    Multiple Line Replace Script?

    nathanwells

      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[i].activate();    
              var aDoc = app.documents[i];    
        
      //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[j];       
                      for (var re in mapObj) {  
                      var newString = aTF.contents.replace(re, mapObj[re])  
                      if (newString != aTF.contents) {        
                          theTF[j].contents = newString;        
                      }        
                  }     
        }  
              }    
          }    
      };        
      FindAndReplaceScript_AllOpenDocuments();     
      
        • 1. Re: Multiple Line Replace Script?
          Silly-V Adobe Community Professional

          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!

          2 people found this helpful
          • 2. Re: Multiple Line Replace Script?
            nathanwells Level 1

            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[i].activate(); 
                    var aDoc = app.documents[i]; 
            
            //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[j];     
                            for (var re in mapObj) {
                            var newString = aTF.contents.replace(new RegExp(re.replace(" "), "i"), mapObj[re])
                            if (newString != aTF.contents) {     
                                theTF[j].contents = newString;     
                            }     
                        }   
              }
                    } 
                }
            
            
            };     
            FindAndReplaceScript_AllOpenDocuments();
            

             

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

            • 3. Re: Multiple Line Replace Script?
              Silly-V Adobe Community Professional

              How about this, change:

               

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

               

              To

               

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

              1 person found this helpful
              • 4. Re: Multiple Line Replace Script?
                nathanwells Level 1

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

                • 5. Re: Multiple Line Replace Script?
                  Silly-V Adobe Community Professional

                  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");

                  1 person found this helpful
                  • 6. Re: Multiple Line Replace Script?
                    nathanwells Level 1

                    That worked!

                    Thank you so much @Silly-V!

                    • 7. Re: Multiple Line Replace Script?
                      pixxxel schubser Level 5

                      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[i].activate();
                              var aDoc = app.documents[i];
                      
                              //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[j];
                                  for (var re in mapObj) {
                                      var newString = aTF.contents.replace(new RegExp(re.replace(/ /g, "[\\s]"), "gi"), mapObj[re]);
                                      if (newString != aTF.contents) {
                                          theTF[j].contents = newString;
                                          }
                                      }
                                  }
                              }
                          }
                      };
                      FindAndReplaceScript_AllOpenDocuments();
                      

                       

                      Your regex knowledgebase will be better and better.

                       

                      Have fun

                       

                      1 person found this helpful
                      • 8. Re: Multiple Line Replace Script?
                        nathanwells Level 1

                        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?

                        • 9. Re: Multiple Line Replace Script?
                          Silly-V Adobe Community Professional

                          Would making it case-sensitive solve this?

                          • 10. Re: Multiple Line Replace Script?
                            nathanwells Level 1

                            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?

                            • 11. Re: Multiple Line Replace Script?
                              Silly-V Adobe Community Professional

                              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?

                              1 person found this helpful
                              • 12. Re: Multiple Line Replace Script?
                                nathanwells Level 1

                                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...

                                • 13. Re: Multiple Line Replace Script?
                                  pixxxel schubser Level 5

                                  Please show us your

                                  List of words to replace

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

                                  We need exact examples.

                                  1 person found this helpful
                                  • 14. Re: Multiple Line Replace Script?
                                    nathanwells Level 1

                                    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[i].activate();   
                                            var aDoc = app.documents[i];   
                                    
                                    //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[j];     
                                                    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[j].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.

                                    • 15. Re: Multiple Line Replace Script?
                                      nathanwells Level 1

                                      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]);
                                      
                                      • 16. Re: Multiple Line Replace Script?
                                        pixxxel schubser Level 5

                                        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[i].activate();
                                            var aDoc = app.documents[i];
                                        
                                            //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[j];
                                                    //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[j].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[k] = "\\b"+re1[k]+"\\b";
                                                }
                                            re1 = re1.join("\\s");
                                            obj2[re1] = obj1[re0];
                                            }
                                        return obj2;
                                        };
                                        

                                         

                                        Have fun

                                         

                                        1 person found this helpful
                                        • 17. Re: Multiple Line Replace Script?
                                          nathanwells Level 1

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