Search code examples
javaregexjava-8ecmascript-5nashorn

Matching Javascript RegEx using Nashorn


How would I evaluate input with a ECMA 262 compliant regular expression?
After some reading I found out the Java 8's javascript engine nashorn can help me to do that.
How can I use nashorn script engine to match a regular expression?


Solution

  • Assume you have a file regex.js containing a method used to determine if a given String matches a given regular expression:

    var check = function(regex, str) {
        return new RegExp(regex).test(str);
    };
    

    You can evaluate this function using the Nashorn script engine, and call it with the following code:

    ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
    engine.eval(new FileReader("regex.js"));
    Invocable invocable = (Invocable) engine;
    Object result = invocable.invokeFunction("check", "\\d+", "1");
    System.out.println(result);
    

    In order to call a function, you first have to cast the script engine to Invocable. This interface is implemented by the NashornScriptEngine and defines a method invokeFunction to call a JavaScript function for a given name. The rest of the method arguments are then directly passed as arguments to the JavaScript method.

    Note that it is also possible to do this without an external JavaScript file. It is also possible to avoid the cast to Invocable by asking the script engine to evalute a String. This is the same code with those two ideas:

    ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
    engine.eval("function check(regex, str) { return new RegExp(regex).test(str); }");
    Object result = engine.eval("check('\\\\d+', 1);");
    System.out.println(result);    
    

    When passing variables from Java to JavaScript, you have to be very careful about the proper escaping of characters: the rule are not the same for the two languages.