簡體   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