我在网站上的面向客户的付款表单中有一个简单的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的错误。您指向规范的链接已经死了,这里缺少IE:
...除了pattern属性是与整个值匹配的,而不仅仅是所有子集(有点像在模式的开头暗示了一个^(?:,而在结尾则暗示了)$)
您实际上可以通过按照自己的模式进行操作来修复此错误-即:
^(?:(|\$)[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})?
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句