6 Replies Latest reply on Jul 5, 2016 7:03 AM by xbytor2

    Regular expression breaks script execution

    Heimdaal Level 1

      I have the following regular expression declaration in my JSX-file:

      var regex = /[^/]*(?=\.[^.]+($|\?))/; // Doesn't work while this does: var regex = /[\u0400-\u04FF]+/;
      


      ...and it breaks the execution of my script for reasons unknown. What's wrong here? I thought the syntax was / theRegEx /
      (commenting away the regex declaration fixes the problem and the script executes normally)

       

      I've tested the regex here:
      RegExr: Learn, Build, & Test RegEx

      ...on this string: "c:/Users/martin.dahlin/Desktop/Test/lolFile.lol"
      which gives me "lolFile" without the quotation marks.

        • 1. Re: Regular expression breaks script execution
          xbytor2 Level 4

          There are parts of RegExp that are not supported or are buggy in PS/JS. If it works in Firefox and/or elsewhere but not in PS/JS, you have to rewrite your regexp and file a bug support with Adobe. I've had problems like this in the past.

           

          If you already have the string isolated, doing this will work as well: File(str).name then use a simpler regexp to strip off the extension.

          For overkill, use this:

           

          //========================= Filename formatting ===============================
          //
          // File.strf(fmt [, fs])
          // Folder.strf(fmt [, fs])
          //   This is based on the file name formatting facility in exiftool. Part of
          //   the description is copied directly from there. You can find exiftool at:
          //      http://www.sno.phy.queensu.ca/~phil/exiftool/
          //
          // Description:
          //   Format a file string using a printf-like format string
          //
          // fmt is a string where the following substitutions occur
          //   %d - the directory name (no trailing /)
          //   %f - the file name without the extension
          //   %e - the file extension without the leading '.'
          //   %p - the name of the parent folder
          //   %% - the '%' character
          //
          // if fs is true the folder is in local file system format
          //   (e.g. C:\images instead of /c/images)
          //
          // Examples:
          //
          // Reformat the file name:
          // var f = new File("/c/work/test.jpg");
          // f.strf("%d/%f_%e.txt") == "/c/work/test_jpg.txt"
          //
          // Change the file extension
          // f.strf("%d/%f.psd") == "/c/work/test.psd"
          //
          // Convert to a file name in a subdirectory named after the extension
          // f.strf("%d/%e/%f.%e") == "/c/work/jpg/test.jpg"
          //
          // Change the file extension and convert to a file name in a subdirectory named
          //   after the new extension
          // f.strf("%d/psd/%f.psd") == "/c/work/psd/test.psd"
          //
          // var f = new File("~/.bashrc");
          // f.strf("%f") == ".bashrc"
          // f.strf("%e") == ""
          //
          // Advanced Substitution
          //   A substring of the original file name, directory or extension may be
          //   taken by specifying a string length immediately following the % character.
          //   If the length is negative, the substring is taken from the end. The
          //   substring position (characters to ignore at the start or end of the
          //   string) may be given by a second optional value after a decimal point.
          // For example:
          //
          // var f = new File("Picture-123.jpg");
          //
          // f.strf("%7f.psd") == "Picture.psd"
          // f.strf("%-.4f.psd") == "Picture.psd"
          // f.strf("%7f.%-3f") == "Picture.123"
          // f.strf("Meta%-3.1f.xmp") == "Meta12.xmp"
          //
          File.prototype.strf = function(fmt, fs) {
            var self = this;
            var name = decodeURI(self.name);
            //var name = (self.name);

            // get the portions of the full path name

            // extension
            var m = name.match(/.+\.([^\.\/]+)$/);
            var e = m ? m[1] : '';

            // basename
            m = name.match(/(.+)\.[^\.\/]+$/);
            var f = m ? m[1] : name;

            fs |= !($.os.match(/windows/i)); // fs only matters on Windows
            // fs |= isMac();

            // full path...
            var d = decodeURI((fs ? self.parent.fsName : self.parent.absoluteURI));

            // parent directory...
            var p = decodeURI(self.parent.name);

            //var p = ((fs ? self.parent.fsName : self.parent.toString()));

            var str = fmt;

            // a regexp for the format specifiers

            var rex = /([^%]*)%(-)?(\d+)?(\.\d+)?(%|d|e|f|p)(.*)/;

            var result = '';

            while (m = rex.exec(str)) {
              var pre = m[1];
              var sig = m[2];
              var len = m[3];
              var ign = m[4];
              var typ = m[5];
              var post = m[6];

              var subst = '';

              if (typ == '%') {
                subst = '%';

              } else {
                var s = '';
                switch (typ) {
                  case 'd': s = d; break;
                  case 'e': s = e; break;
                  case 'f': s = f; break;
                  case 'p': s = p; break;
                  // default: s = "%" + typ; break; // let others pass through
                }

                var strlen = s.length;

                if (strlen && (len || ign)) {
                  ign = (ign ? Number(ign.slice(1)) : 0);
                  if (len) {
                    len = Number(len);
                    if (sig) {
                      var _idx = strlen - len - ign;
                      subst = s.slice(_idx, _idx+len);
                    } else {
                      subst = s.slice(ign, ign+len);
                    }
                  } else {
                    if (sig) {
                      subst = s.slice(0, strlen-ign);
                    } else {
                      subst = s.slice(ign);
                    }
                  }

                } else {
                  subst = s;
                }
              }

              result += pre + subst;
              str = post;
            }

            result += str;

            return result;
          };
          Folder.prototype.strf = File.prototype.strf;

          1 person found this helpful
          • 2. Re: Regular expression breaks script execution
            pixxxel schubser MVP & Adobe Community Professional

            I don't know how you use this regex. Perhaps this easier variant can help you?

            \w+(?=\..{2,4}$)

            • 3. Re: Regular expression breaks script execution
              xbytor2 Level 4

              As I said before, ExtendScript has had problems with otherwise valid regexp expressions. /.+\.([^\.\/]+)$/ had been the most commonly used regexp for extracting file extensions and has worked in all versions of ExtendScript. Also, ExtendScript has had problems with \w with non LATIN1 characters in the past so I avoid it whenever possible.

               

              -X

              1 person found this helpful
              • 4. Re: Regular expression breaks script execution
                Pedro Cortez Marques Level 3

                In javascript, when I wanto to get a bunch of specific folders, I use new RegExp(a,b) like this:

                new RegExp (a, b)
                

                a >> [String] my regular expression (don't use the / caracter before and after

                b >> [String]  "g" or "i" or "gi", ...  (second argument is optional)

                 

                Example:

                var myReg= new RegExp( "[^\_|a-zA-Z|0-9][A-Z][0-9]{8}$");
                var all = Folder([myFolder]).getFiles(myReg).sort();
                

                 

                Another example I use (this one accepts all lower/uppercase letters:

                var ID = 12345678;
                var regthis = new RegExp( "((([x-z]{1}?)[a-v]{1}[_|c]{1})?)"+ID.toString(),"i");
                var sameIDfolders = Folder([myFolder]).getFiles(regthis);
                
                • 5. Re: Regular expression breaks script execution
                  matias.kiviniemi Level 3

                  xbytor is right, there's really no "regex-standard/compliance". Basic things work pretty universally, but there are platform specific features and conventions and you just need to test & work around them.

                   

                  That said, entering your regex to Online regex tester and debugger: JavaScript, Python, PHP, and PCRE gives and error "/ Unescaped delimiter", i.e. should be "/[^\/]*(?=\.[^.]+($|\?))/". Also using the explicit constructor is a tad safer way, typos result more sensible errors.

                  1 person found this helpful
                  • 6. Re: Regular expression breaks script execution
                    xbytor2 Level 4

                    This: var myReg= new RegExp( "[^\_|a-zA-Z|0-9][A-Z][0-9]{8}$");

                    should probably be this: var myReg= new RegExp( "[^\\_|a-zA-Z|0-9][A-Z][0-9]{8}$");

                    because of escapes in JS strings. Like matias said, it's just better to use RegExp constants than strings unless you have string reason to and you do adequate testing.

                    1 person found this helpful