【问题标题】:JavaScript RegEx Fails In IE / FirefoxJavaScript RegEx 在 IE / Firefox 中失败
【发布时间】:2017-09-27 22:04:00
【问题描述】:

我遇到了在 Internet Explorer 和 Firefox 中无法评估的正则表达式匹配问题。它在 Chrome 和 Opera 中运行良好。我知道 Chrome 通常对错误的容忍度要高得多,所以我怀疑我在这个过程中把球丢到了某个地方——但似乎没有一个在线评估工具在我的表达中发现任何错误。很抱歉,这是一个令人费解的表达方式,但希望有些东西很容易成为罪魁祸首。表达式如下:

keyData = data.match(/\w+\u0009\w+\u0009[\u0009]?\w+\u0009([-]?\w+|%%)[@]?\u0009([-]?\w+|%%)[@]?\u0009([-]?\w+|%%)[@]?(\u0009([-]?\w+|%%)[@]?)?(\u0009([-]?\w+|%%)[@]?)?(\u0009([-]?\w+|%%)[@]?)?\u0009\u0009\/\//g);

'data' 是我正在解析的文本文件,没有错误。我不会在这里发布整个文件,但我希望匹配的是以下内容:

10  Q       1   0439    0419    -1      // CYRILLIC SMALL LETTER SHORT I, CYRILLIC CAPITAL LETTER SHORT I, <none>

我相信,当我在此处发布字符串时,它会删除“u0009”字符,因此如果您想查看其中一个完整文件,我已经链接了一个here。如果还有什么我可以澄清的,请告诉我!

编辑:
我在这篇文章中的目标不仅是了解为什么会失败,而且还要了解这个表达式是否格式正确。

经过进一步审查,似乎是 Internet Explorer 和 Firefox 解析文本文件的方式存在问题。他们似乎去掉了标签并用空格替换它们。我尝试更新表达式,它在在线验证器中匹配没有问题,但在 IE/FF 中仍然失败。

编辑 2
此后,我考虑到反馈,将我的表达方式更新为更清晰的形式。这个问题仍然存在于 IE 和 Firefox 中。这似乎是字符串本身的问题。 IE 不会让我匹配一个以上的字符,无论我的表达是什么。例如,如果文件的字符串是KEYBOARD,我尝试匹配/\w+/,它只会返回K

/[0-9](\w)?(\t+|\s+)\w+(\t+|\s+)[0-9](\t+|\s+)(-1|\w+@?|%%)(\t+|\s+)(-1|\w+@?|%%)(\t+|\s+)(-1|\w+@?|%%)((\t+|\s+)(-1|\w+@?|%%))?((\t+|\s+)(-1|\w+@?|%%))?((\t+|\s+)(-1|\w+@?|%%))?(\t+|\s+)\/\//g

【问题讨论】:

  • 我最初使用的是\u0009,因为我没有意识到\它等同于\t。更具体地说,在开发我的表达式时,我正在检查文本文件中的字符,它不是标准空格,所以我检查了 unicode 字符,它说\u0009,所以我就用它了。使用\t 会更紧凑。感谢您的提示!
  • 仅供参考。 (\t+|\s+) 是多余的,因为 \s 包含 \t。而[0-9] 可以简化为\d。所以\d(\w)?(\s+)\w+(\s+)\d(\s+)(-1|\w+@?|%%)(\s+)(-1|\w+@?|%%)(\s+)(-1|\w+@?|%%)((\s+)(-1|\w+@?|%%))?((\s+)(-1|\w+@?|%%))?((\s+)(-1|\w+@?|%%))?(\s+)\/\/ 是一个有点的简化版。
  • 另外,捕获组真的是有意的吗?它们主要捕获碎片和空间。
  • 啊!那看起来更好。我没有意识到\s 处理了\t 但这确实有道理。好记。我不确定你所说的捕获组是什么意思——我使用这个表达式作为一个整体匹配,所以如果组返回位,它们都加起来是一个完整的匹配,对吗?

标签: javascript jquery regex


【解决方案1】:

在研究了我的正则表达式一段时间后,我怀疑 IE 与 Chrome 相比实际上读取文本文件的方式有问题。具体来说,如果我在文本文件中有字符串KEYBOARD,并且我尝试使用/\w+/ 匹配它,它只会在IE 中返回K,但在Chrome 中它将匹配整个字符串KEYBOARD。我怀疑 IE 在字符之间插入了一些死区,所以我遍历了文件的前几个字符并打印了它们的 unicode 等价物。

for (i = 0; i < 30; i++) {
    console.log(data.charCodeAt(i) + ' ' + data[i]);
}

这证实了我的怀疑,我看到u0000 在每个字符之间弹出。我不确定为什么每个字符之间有 NULL 字符,但为了解决我的问题,我只是执行了: 数据 = data.replace(/\u0000+/g, ''); 这完全解决了我的问题,我可以使用表达式正常解析我的字符串:

keyData = data.match(/[0-9](\w)?(\t+|\s+)\w+(\t+|\s+)[0-9](\t+|\s+)(-1|\w+@?|%%)(\t+|\s+)(-1|\w+@?|%%)(\t+|\s+)(-1|\w+@?|%%)((\t+|\s+)(-1|\w+@?|%%))?((\t+|\s+)(-1|\w+@?|%%))?((\t+|\s+)(-1|\w+@?|%%))?(\t+|\s+)\/\//g);

【讨论】:

  • 可能是文件是 UTF-16 并且您正在读取为 ASCII 或 UTF-8 吗?这样就可以解释了。
  • 下载了链接文件并确认它是 UTF-16(或 UCS-2)所以问题是,你如何读取它?
  • 我正在使用简化的 AJAX 获取命令 $.get('file.klc', function(data) { }); 读取文件。我想我应该检查编码,因为它是从另一个程序导出的。你是说它在服务器端的编码是如何导致这个问题的,还是它被读取后是如何编码的?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多