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?
-
I'm a bit confused by your question. You're asking how to use process ECMAScript regular expressions via the Nashorn JS engine in Java 8? Is there any reason you don't just use Java's regular expressions? Where is this being done (server/client side)?JNYRanger– JNYRanger2015-09-14 18:27:33 +00:00Commented Sep 14, 2015 at 18:27
-
@JNYRanger For your first question - Yes. That's what I'm asking. Nashorn is built on ECMA specification so there should not be any trouble doing that.<br/> Because Javascript RegEx is different from Java RegEx.Himanshu Yadav– Himanshu Yadav2015-09-14 18:37:04 +00:00Commented Sep 14, 2015 at 18:37
-
I understand that JavaScript regex is different syntactically, but my question is in regards to why you want to use JavaScript regex as opposed to Java regex considering the RegEx engine in both languages offers the same feature set. Where are you getting the pattern from? You may want to instead consider performing a conversion between the Java & JavaScript regex syntaxes, which would be far easier to do: stackoverflow.com/a/8754472/2359643JNYRanger– JNYRanger2015-09-14 18:48:36 +00:00Commented Sep 14, 2015 at 18:48
-
@JNYRanger I am using swagger to write a validation framework. Swagger is based on yaml. Yaml which is super set of Json Schema, allows regex on ECMA standard. Hope this is clear enough.Himanshu Yadav– Himanshu Yadav2015-09-14 23:45:50 +00:00Commented Sep 14, 2015 at 23:45
-
Makes a lot of sense now!JNYRanger– JNYRanger2015-09-15 12:53:09 +00:00Commented Sep 15, 2015 at 12:53
3 Answers
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.
1 Comment
Perhaps something like this:
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine se = manager.getEngineByName("nashorn");
se.put("str", "the quick brown fox");
se.put("rgx", "/quick/");
Object result = se.eval("str.matches(rgx).length");
System.out.println(result);
You need to run with Java8 to get the "nashorn" engine. The argument to se.eval(String) is the javascript. I kept it simple for this example. You can do plenty other stuff in terms of regex. See here.
Comments
Using Java 8 you can use the Nashorn JavaScript engine via the package javax.script using the nashorn identifier.
Here's an example:
ScriptEngineManager engineManager = new ScriptEngineManager();
ScriptEngine nashorn = engineManager.getEngineByName("nashorn");
String ecmaScript = //YOUR SCRIPT HERE
//add any additional variables here
Object returnVal = nashorn.eval(ecmaScript);
SOURCE: http://www.oracle.com/technetwork/articles/java/jf14-nashorn-2126515.html
You'll want to get familar with the ScriptEngine class and you'll need to do quite a bit of testing and trial & error to handle the data that's returned since the returned data won't be type safe. The debugger will be your best friend during this process.