繁体   English   中英

浏览器是否支持不同的HTML5模式正则表达式功能?

[英]Do browsers support different HTML5 pattern regexp features?

我在我们的网站上以面向客户的付款方式提供了一个简单的RegEx模式:

<input type="text" pattern="(|\$)[0-9]*(|\.[0-9]{2})"
       title="Please enter a valid number in the amount field" required>

添加它是为了在客户端无法输入有效号码时快速通知客户,然后再进行服务器端验证。

在四个客户打电话抱怨他们无法提交表格因为他们的浏览器不断告诉他们他们输入的金额不正确之后,我做了一些挖掘并发现IE10 +不喜欢该表达式的背面 - 任何输入的金额这包括小数点被接受,带有小数点东西被拒绝。 该模式适用于我的开发环境(Chrome 30+)和Opera 12,但Firefox 27根本不会验证它。

我阅读了规格 ,其中只说:

如果指定,则属性的值必须与JavaScript Pattern生成匹配。 [ECMA262]

由于支持pattern的唯一浏览器能够支持ECMAScript 5 ,我认为这包括所有Javascript正则表达式的完全支持。

在哪里可以了解更多有关不同浏览器中pattern支持之间的怪癖的信息?

这个问题似乎只是一个IE浏览器的bug。 您对规范的链接已经过时了,继承人IE缺失了:

...除了模式属性与整个值匹配,而不仅仅是任何子集(有点像暗示了^(在模式的开头是?)和最后的$)

你可以通过你自己的模式来实际修复这个bug - 即:

^(?:(|\$)[0-9]*(|\.[0-9]{2}))$

这对我来说在IE9和IE10以及Chrome中都很有用。 看到更新的小提琴

发生这种情况的技术原因有点复杂:

如果您在15.10.2.3节中阅读了EMCA 5.1规范,那么它将讨论如何评估变更。 基本上,每个“部件”的| 从左到右进行评估,直到找到匹配的一个。 除非“续集”中存在问题,否则假定该值,在这种情况下,评估交替中的其他可能性。

看起来IE正在做的是使用替换的空白部分匹配字符串的开头,它的工作原理是: \\$[digits][empty]匹配$12.12的起点到小数点。 IE的正则表达式引擎(正确)说这是匹配,因为子字符串匹配,并且没有被告知要检查字符串的末尾。

一旦正则表达式引擎(没有强制整个字符串匹配的锚点)返回true,表示匹配,Microsoft的一些工程师采用了一个快捷方式并告诉pattern属性也检查匹配的部分是否等于整个字符串,并且失败来自哪里。 引擎只匹配字符串的一部分,即使它可能匹配更多,所以二次检查失败,认为最后有无关的输入。

这个案子是微妙的,所以我不会感到惊讶它以前没有被抓住过。 我创建了一个错误报告https://connect.microsoft.com/IE/feedback/details/836117/regex-bug-in-pattern-validator ,看看是否有来自Microsoft的回复。

这与EMCA规范有关的原因是,如果发动机被告知匹配整个字符串,当它达到小数点并且试图匹配交替的第二部分时,它会回溯,找到并匹配(\\.[0-9{2}) ,整个事情都会奏效。


现在,对于一些解决方法:

  • 将锚点^(?:)$到模式中

  • 不要使用空的交替。 就个人而言,我喜欢使用可选的$代替这些情况。 你的模式变成了(\\$?)[0-9]*(\\.[0-9]{2})? 会工作吗? 是一个贪婪的匹配,如果可能,引擎将消耗整个字符串,而不是交替,这是第一次匹配

  • 在您的变更上交换订单。 如果首先测试较长的字符串,它将首先匹配,并首先使用。 这已经出现在其他语言中 - 为什么要在此RegEx中进行更换?

PS:小心你的数字* 现在,“$”是有效匹配,因为*允许0位数。 我对你的完整正则表达式的建议是(\\$)?(\\d+)(\\.\\d{2})?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM