2
votes

I've been struggling to solve a problem recently regarding the compilation of javascript regular expressions during the compression/minimization stage of our ant build task.

Basically, the problem is that every javascript regular expression, ie:

var x = y.replace(/(\d|\.)/g, '');

gets its escape characters chomped up and replaced as follows:

var x = y.replace(/(d|.)/g, '');

This has become really annoying as the project is progressing rapidly and my tests keep failing because of issues like these during the build stage.

These are the things that I have tried:

Compiler Tools:

Different ways to form regular expressions:

// Same problem occurs when regex placed inside a string
var x = y.replace(new RegExp('(\\d|\\.)', 'g'), ''); 

Different ways to call the compiler/compressor from within Ant:

<!-- Closure Compiler Ant Task -->
<taskdef name="jscomp" classname="com.google.javascript.jscomp.ant.CompileTask"
         classpath="lib/compiler.jar"/>

<!-- Executable called from command line -->
<exec executable="java" dir=".">
         <arg line="-jar lib/compiler.jar" />
         <!-- other args -->
</exec>

Different operating systems from where to run the Ant task from:

  • Mac OSX
  • Windows 7
  • Unix

Any ideas on how to proceed here?

I find it too much of a coincidence that BOTH the Closure Compiler and YUI Compressor would suffer from the problem parsing regexes so perhaps the problem is somewhere else...

Any input much appreciated.

UPDATE

As mentioned by Chad below, the Closure Compiler service does not report the same problem, meaning that the problem must be in the way ANT (or the underlying console processes) handle input/output strings.

The way this is done at the moment is via a (google) compiler ant task by using the SAME FILE as input and output for the process (NOTE that the same problem occurred via using command line call).

<!-- CLOSURE COMPILER MACRO -->
<!-- @see http://code.google.com/p/closure-compiler/wiki/BuildingWithAnt -->
<macrodef name="compile">
    <attribute name="file" />
    <sequential>
        <echo>Compiling @{file}</echo>
        <jscomp compilationLevel="simple" warning="quiet"
                debug="false" output="@{file}">
            <sources dir=".">
                <file name="@{file}"/>
            </sources>
        </jscomp>
    </sequential>
</macrodef> 

<!-- ACTUAL USAGE -->
<compile file="${local.output.dir}/app.js" />
2
Can you provide the javascript you're trying to compile?DCoder
Have you tried using the character brackets instead? /[\d\.]/gErr
@DCoder: here is are two examples: var number = value.match(/(\d|\.)+/gi)[0];, /\d+$/gi.test(zoneBox.text()) Please remember: Im not trying to work around this problem but to solve it so we can use regular expressions. @Err, I've tried using character brackets and the result is the same. The problem is basically that the escape characters are removed, regardless of the structure of the regular expression.Steven de Salas
Have you tried calling the compilers with the same args manually (what args are you using)? Is input/output handled by ant or by the environment (if you are passing only filenames to the compiler and redirecting its output to a file on the command line, ant should not have any way to mess this up)? I honestly can't see how this could happen, unless somewhere the processed output is being processed and the escape character gets consumed.DCoder
Make sure you use the latest version of Closure-compiler. Testing at closure-compiler.appspot.com/home did not exhibit the same issues you mentioned.Chad Killingsworth

2 Answers

3
votes

I unable to reproduce this problem here:

http://closure-compiler.appspot.com/home

This code:

// ==ClosureCompiler==
// @compilation_level SIMPLE_OPTIMIZATIONS
// @output_file_name default.js
// @formatting pretty_print
// ==/ClosureCompiler==

y.replace(/(\d|\.)/g, '');

is compiled to:

y.replace(/(\d|\.)/g, "");

It seems like something else is changing your code, do you do any pre- or post-processing of your scripts?

1
votes

This answer doesn't address the general mystery of what tool in your build process is causing mischief, but it does deal with the specific regex you want to match. As other posters have noted, . (dot) inside a character class doesn't need to be escaped. So

var x = y.replace(/(\d|\.)/g, '');

can be rewritten without backslashes as

var x = y.replace(/([0-9.])/g, '');

and I don't think you need the parentheses for capturing in this case, so we can say

var x = y.replace(/[0-9.]/g, '');