2

I am developing a SmartTV web app using JavaScript. I want to write a regular expression which validate the local mobile operator codes:

op_codes = [33, 50, 63, 66, 67, 68, 73, 93, 95, 96, 97, 98, 99]

My code works as it should in Chrome and LG webOS. But in Samsung Tizen RegExp.test returns false even though it should be true.

Code sample:

var val = '0985739341',
    op_codes = [33, 50, 63, 66, 67, 68, 73, 93, 95, 96, 97, 98, 99],
    pattern = new RegExp('^0'+'('+op_codes.join('|')+')'+'\\d{7}$');

console.log(pattern.test(val)); //Samsung Tizen output: false

Here is the screenshot of Tizen console:

Tizen console(Updated)

I can't figure out what is wrong with my code, how can I solve it?

Same code executed on Chrome and Tizen:
Tizen(left) Chrome(right) console

Same variable Chrome and Tizen:

How it can be?

1 Answers1

0

New Answer

Your latest screenshot (here) tells us that you have an invisible character in val. I really, really, really should have thought of that earlier. Apparently for whatever reason, whatever your source is for val, it's including an invisible character in it.

You'll need to identify it and, ideally, figure out where it comes from and fix it; otherwise, strip it out.

To figure out what it is, try this:

console.log("val", val);
Array.prototype.forEach.call(val, function(ch) {
    console.log(ch.charCodeAt(0).toString(16));
});

If it were the value it seems to be, you'd get

val 0985739341
30 39 38 35 37 33 39 33 34 31

Live Copy:

var val = "0985739341";
console.log("val", val);
console.log(Array.prototype.map.call(val, function(ch) {
    return ch.charCodeAt(0).toString(16);
}).join(" "));

...but I bet you get something else. It could be any of several invisible characters — a zero-width space (U+200B), a zero-width non-joiner (U+200C), etc. Here's an example with both of those:

var val = "0985\u200C\u200B739341";
console.log("val", val);
console.log(Array.prototype.map.call(val, function(ch) {
    return ch.charCodeAt(0).toString(16);
}).join(" "));

Once you know what it is, you can find out where it comes from and get rid of it (or strip it from the string afterward).

Old, Probably-Incorrect Answer

I can't figure out what is wrong with my code...

If that screenshot is genuine, then there's nothing wrong with your code; there's a bug in the JavaScript engine being used on that device. This would appear to be one of the rare cases where the rule "select isn't broken" fails. (Would appear to be, keep being skeptical and keep double-checking yourself.)

You'll have to experiment to see where it fails (and file an appropriate bug report) and work around it. For instance, maybe the implementation of test incorrectly ignores capture groups and so isn't applying | correctly, or new RegExp is just fundamentally broken, or... It'll take a lot of experimentation to figure it out.

Below are your original validation (validate1) and three alternatives you might try. The second (validate2) uses a non-capturing group instead of a capturing group. They should be the same as far as test is concerned, but then again, your original code should work. :-)

var val = '0985739341';
var op_codes = [33, 50, 63, 66, 67, 68, 73, 93, 95, 96, 97, 98, 99];
var val1PatternStr = '^0'+'('+op_codes.join('|')+')'+'\\d{7}$';
var val1Pattern = new RegExp(val1PatternStr);
var val2PatternStr = '^0'+'(?:'+op_codes.join('|')+')'+'\\d{7}$';
var val2Pattern = new RegExp(val2PatternStr);

console.log(1, validate1(val));
console.log(2, validate2(val));
console.log(3, validate3(val));
console.log(4, validate4(val));
    
function validate1(val) {
    return val1Pattern.test(val);
}

function validate2(val) {
    return val2Pattern.test(val);
}

function validate3(val) {
    return val.length === 10 &&
           val[0] == "0" &&
           op_codes.indexOf(+val.substring(1,3)) != -1 &&
           /^\d+$/.test(val.substring(3));
}

function validate4(val) {
    return val.length === 10 &&
           val[0] == "0" &&
           op_codes.indexOf(+val.substring(1,3)) != -1 &&
           sillyIsDigit(val[3]) &&
           sillyIsDigit(val[4]) &&
           sillyIsDigit(val[5]) &&
           sillyIsDigit(val[6]) &&
           sillyIsDigit(val[7]) &&
           sillyIsDigit(val[8]) &&
           sillyIsDigit(val[9]);
}

function sillyIsDigit(ch) {
    return ch >= "0" && ch <= "9";
}

If the JavaScript engine chokes on val[0], you'll have to change all of those [] on val to calls to charAt instead: val[0] => val.charAt(0).

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Thx, everything working fine(Look at the Tizen console screenshot in my question). I'll try to test this bug and find where it appears. – La_Concorde Oct 05 '17 at 09:20
  • @La_Concorde Glad it's working! But I'm confused by the latest screenshot. Why the `\\` between `^` and `0`? And my `validate1` is the same as your original code, I don't see why it would suddenly magically work...? – T.J. Crowder Oct 05 '17 at 09:52
  • Precisely, early was overjoyed it is not working with your solutions. My typo mislead me.)) I was add new screenshot with the same code was executed in Chrome and Tizen.I'm even more confused than before. – La_Concorde Oct 05 '17 at 11:11
  • can you explain me the output showed on the third screenshot in my answer? I am really confused. – La_Concorde Oct 05 '17 at 11:43
  • @La_Concorde: Yes: An invisible character. I've updated the answer. :-) – T.J. Crowder Oct 05 '17 at 15:15
  • http://joxi.ru/vAWR0OeI1Zjap2 Look at this screenshot, please, my invisible character is `d`. Tell me please why I do not see this character in console in browser? How can I avoid it? – La_Concorde Oct 07 '17 at 08:56
  • @La_Concorde: To my surprise, the console just doesn't show carriage returns (that's what that character is, `\r`). I can't tell you how to avoid it, something is inserting those carriage returns between the digits. You can easily remove them (`val = val.replace(/\r/g, "");` but if I were you I'd find out what's inserting them in the first place. – T.J. Crowder Oct 07 '17 at 09:15
  • Thx, this fixed my problem. I will follow your advice and I'll look where it comes from. – La_Concorde Oct 07 '17 at 18:17