Javascript将"%%"读作"%"和"%%"?

lon*_*556 14 javascript

在编写测试时,我正在比较字符串.测试结果为失败.我手动复制粘贴字符串,它的工作原理...注意mysql字符串语法; 但到目前为止它永远不会触及mysql.

Console.logged copy + paste两个字符串看起来像这样:

console.log(replaced);
"SELECT COUNT(*) FROM interaction WHERE ambassador_name LIKE '%' AND influencer_name = ?"

console.log(sqlQuery0);
"SELECT COUNT(*) FROM interaction WHERE ambassador_name LIKE '%' AND influencer_name = ?"
Run Code Online (Sandbox Code Playgroud)

它不应该失败,但确实如此.所以我想看看它失败的地方:

it( "submits the proper first sql query", function(){
  var replaced = dao.SQLquery[0].replace(/  +/g, ' ');
  for (var i = 0; i < replaced.length; i++) {
    if (replaced[i] != sqlQuery0[i] ){
      console.log(replaced.slice(i-10,i+10));
      console.log(sqlQuery0.slice(i-10,i+10);
      break
    }
  }
})
Run Code Online (Sandbox Code Playgroud)

到我的上面回来了这个...

me LIKE '%' AND inf
me LIKE '%' AND infl
Run Code Online (Sandbox Code Playgroud)

它们的长度不一样......对.我再试一次.

  it( "submits the proper first sql query", function(){
    var replaced = dao.SQLquery[0].replace(/  +/g, ' ');
    for (var i = 0; i < replaced.length; i++) {
      if (replaced[i] != sqlQuery0[i] ){
        console.log('|'+ replaced.slice(i-10,i+10)+'|',replaced.slice(i-10,i+10).length);
        console.log('|'+sqlQuery0.slice(i-10,i+10)+'|',sqlQuery0.slice(i-10,i+10).length);
        break
      }
    }
  })
Run Code Online (Sandbox Code Playgroud)

令我更大的惊喜:

|me LIKE '%' AND inf| 20
|me LIKE '%' AND infl| 20
Run Code Online (Sandbox Code Playgroud)

但是第一个字符串只有19个长度!

我最后的嫌疑人:

var replaced = dao.SQLquery[0].replace(/  +/g, ' ');
for (var i = 0; i < replaced.length; i++) {
  console.log(replaced[i], sqlQuery0[i]);
  if (replaced[i] != sqlQuery0[i] ){
    console.log('|'+ replaced.slice(i-10,i+10)+'|',replaced.slice(i-10,i+10).length);
    console.log('|'+sqlQuery0.slice(i-10,i+10)+'|',sqlQuery0.slice(i-10,i+10).length);
    break
  }
}
Run Code Online (Sandbox Code Playgroud)

给了我这个:

n n
a a
m m
e e

L L
I I
K K
E E

' '
% %
% '
|me LIKE '%' AND inf| 20
|me LIKE '%' AND infl| 20
Run Code Online (Sandbox Code Playgroud)

显然"%%"被解释为%和%%这怎么可能?

更多:

var replaced = dao.SQLquery[0].replace(/  +/g, ' ');
console.log(sqlQuery0)
for (var i = 0; i < replaced.length; i++) {
  console.log(replaced[i], sqlQuery0[i]);
  if (replaced[i] != sqlQuery0[i] ){
    console.log('|'+ JSON.stringify(replaced.slice(i-10,i+10))+'|',replaced.slice(i-10,i+10).length);
    console.log('|'+ JSON.stringify(sqlQuery0.slice(i-10,i+10))+'|',sqlQuery0.slice(i-10,i+10).length);
    console.log('|'+ JSON.stringify(dao.SQLquery[0].slice(i-10,i+10))+'|',sqlQuery0.slice(i-10,i+10).length);
    break
  }
}

|"me LIKE '%' AND inf"| 20
|"me LIKE '%' AND infl"| 20
|"ame LIKE '%' AND in"| 20
Run Code Online (Sandbox Code Playgroud)

Rob*_*son 7

扩展@Matt Ball和@blm所说的内容,你很可能在"替换"变量中的文本中有一个"隐形"字符.要对此进行测试,请使用十六进制编辑器并粘贴"被替换"和sqlQuery0变量中的文本 - 您应该能够看到'%'字符周围有一个不可见的字符,如'00'NUL或'1E'记录分隔符.

您可以使用此在线Hex Viewer来测试https://hexed.it/?hl=en

要查看我所指的ASCII码,请查看ascii表http://www.asciitable.com/


N. *_*avy 2

正如其他人所指出的,其中一个字符串中可能存在某种隐藏的 Unicode 字符。最好的查看方法是使用charCodeAt()查看实际存在的代码点。

\n\n

例如:

\n\n
var a = \'foo\\u200bbar\';\nvar b = \'foobar\';\n\nconsole.log(\'a = "\' + a + \'"\');\nconsole.log(\'b = "\' + b + \'"\');\n\nfunction toCodePointArray(str) {\n    var result = [];\n    for (var i = 0; i < str.length; i++) {\n        result.push(str.charCodeAt(i));\n    }\n    return result;\n}\n\nconsole.log(\'toCodePointArray(a) = \', toCodePointArray(a));\nconsole.log(\'toCodePointArray(b) = \', toCodePointArray(b)); \n
Run Code Online (Sandbox Code Playgroud)\n\n

当我运行这个时,我得到:

\n\n
a = "foo\xe2\x80\x8bbar"\nb = "foobar"\ntoCodePointArray(a) =  [ 102, 111, 111, 8203, 98, 97, 114 ]\ntoCodePointArray(b) =  [ 102, 111, 111, 98, 97, 114 ]\n
Run Code Online (Sandbox Code Playgroud)\n\n

这里隐藏的字符清楚地显示为 8203,它是 0x200b 的十进制等价物,它是 Unicode 零宽度空间。

\n