3

The regular expression is "(\d+)|(N\A)", which matches digits or string "N\A". It works in Java, but not in JavaScript.

  1. Results are different between Java and JavaScript.
  2. Results of two versions in JavaScript are different.

What's wrong I made?

Code code snippet:

Java

Environment: JDK 1.8.0_144

String orderNumberRegExp = "(\\d+)|(N/A)";
System.out.println("12345".matches(orderNumberRegExp));

String digitalOnly = "\\d+";
System.out.println("12345".matches(digitalOnly));
System.out.println("12345ABC".matches(digitalOnly));

Output (as my expected):

true
true
false

JavaScript

Environment: node v9.8.0

The two versions return wrong results both.

Version 1:

var orderNumberRegExp = new RegExp("(\d+)|(N\/A)"); // or "(\d+)|(N/A)"
console.log(orderNumberRegExp.test("12345"));

var digitalOnly = new RegExp("\d+");
console.log(digitalOnly.test("12345"));
console.log(digitalOnly.test("12345ABC"));

Output:

false
false
false

Version 2:

var orderNumberRegExp = /(\d+)|(N\/A)/
console.log(orderNumberRegExp.test("12345"));

var digitalOnly = /\d+/;
console.log(digitalOnly.test("12345"));
console.log(digitalOnly.test("12345ABC"));

Output:

true
true
true

Thanks for all your help. My code has issues:

  1. When to create regular expression using RegExp(), the backslash should be escaped. (@LukStorms, @grzegorz-oledzki, and @benny) (Also Ref to the demo from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp)
  2. The test method is different from the matches method in Java. It should add ^ and $ to assert the start and end of the string. (More details in the answer by @sweeper )

So, code can be:

var orderNumberRegExp = new RegExp("^(\\d+)$|^(N/A)$");
console.log(orderNumberRegExp.test("12345")); // true
console.log(orderNumberRegExp.test("N/A")); // true
console.log(orderNumberRegExp.test("12345ABC")); // false
console.log(orderNumberRegExp.test("ABC1234")); // false

var digitalOnly = new RegExp("^\\d+$");
console.log(digitalOnly.test("12345")); // true
console.log(digitalOnly.test("12345ABC")); // false

The regular expressions can also be:

var orderNumberRegExp = /^(\d+)$|^(N\/A)$/
var digitalOnly = /^\d+$/
Iridium Cao
  • 51
  • 1
  • 8

2 Answers2

6

The test method is different from the matches method in Java.

RegEx.prototype.test() returns true whenever a match is found in the string, whereas Matcher.matches() returns true only if the whole string matches the pattern. So the JavaScript test() is more similar to the Java Matcher.find() than to Matcher.matches().

To make your Javascript regexes work, you need to add ^ and $ to assert the start and end of the string:

    var orderNumberRegExp = /^(?:(\d+)|(N\/A))$/
    console.log(orderNumberRegExp.test("12345"));
    
    var digitalOnly = /^\d+$/;
    console.log(digitalOnly.test("12345"));
    console.log(digitalOnly.test("12345ABC"));

This will simulate the behaviour of Matcher.matches()

Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • 1
    Nice answer with great explanations +1! (I took the freedom to add the code snippet) sorry for that ;-) – Allan Mar 15 '18 at 06:42
  • This `^(\d+)|(N\/A)$` should be this `^(?:(\d+)|(N\/A))$`. And you didn't mention why RegExp returned false for all input strings which I think is the first issue with his code. – revo Mar 15 '18 at 08:39
2

Try var digitalOnly = new RegExp("\\d+");

Benny Halperin
  • 1,872
  • 3
  • 13
  • 18