<div class="formRow">
<label for="phone">Phone number</label>
<input name="custPhone" id="phone" type="tel" placeholder="(nnn) nnn-nnnn"
pattern="^\d{10}$|^(\(\d{3}\)\s*)?\d{3}[\s-]?\d{4}$" >
</div>
Run Code Online (Sandbox Code Playgroud)
这来自一本教科书(尽管已经有几年了),我不知道为什么浏览器只接受任何内容。
任何人都可以看到是什么可能阻止正则表达式完成其工作以验证 7 或 10 位电话号码并拒绝其他模式?
当我只使用表达式并在 regex101.com 上进行测试时,该表达式似乎在那里完成了它的工作。
^\d{10}$|^(\(\d{3}\)\s*)?\d{3}[\s-]?\d{4}$
在 regex101.com 上,1234567 将匹配,1234567890 将匹配,其他少于 7、多于 10 的模式以及包含 8 和 9 位数字的模式将被拒绝。
教科书的其他正则表达式验证很好。它似乎与浏览器无关,因为它在两种不同的浏览器上失败。
VLA*_*LAZ 16
提供给属性的值pattern将转换为带有unicode 集v标志的正则表达式。
HTML 标准定义:
输入元素的已编译模式正则表达式(如果存在)是 JavaScript RegExp 对象。其确定如下:
如果该元素没有
pattern指定属性,则不返回任何内容。该元素没有已编译的模式正则表达式。令pattern
pattern为元素属性的值。令regexpCompletion为 RegExpCreate( pattern , "v")。
如果regexpCompletion是突然完成,则不返回任何内容。该元素没有已编译的模式正则表达式。
令anchoredPattern为字符串“^(?:”,后跟pattern,后跟“)$”。
返回 !RegExpCreate(锚定模式,“v”)。
在v(unicode 集) 模式下,必须转义字符类内的单个破折号(以及在外部有效的其他值v),即使它位于括号旁边。演示:
const nonV = new RegExp(/[a-]/);
console.log('nonV match "a"', nonV.test("a"));
console.log('nonV match "-"', nonV.test("-"));
console.log('nonV match "b"', nonV.test("b"));
try {
const v = new RegExp(/[a-]/, "v"); // throws an error
console.log('v match "a"', v.test("a"));
console.log('v match "-"', v.test("-"));
console.log('v match "-"', v.test("b"));
} catch (error) {
console.error("cannot use unescaped dash:", error.message)
}
const vEscaped = new RegExp(/[a\-]/, "v");
console.log('vEscaped match "a"', vEscaped.test("a"));
console.log('vEscaped match "-"', vEscaped.test("-"));
console.log('vEscaped match "b"', vEscaped.test("b"));Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper { max-height: 100% !important }Run Code Online (Sandbox Code Playgroud)
u这于 2023 年 4 月从之前的(unicode)标志更改为v(unicode set),从而导致使用pattern具有某些未转义值的属性的 HTML 发生重大更改。在针对 HTML 标准这一更改的 GutHub Pull 请求中,Mathias Bynens 表示:
[重大更改]一些以前有效的模式现在是错误的,特别是那些字符类包含未转义特殊字符
()[]{}/-\|或双标点符号的模式:Run Code Online (Sandbox Code Playgroud)pattern="[(]" pattern="[)]" pattern="[[]" pattern="[{]" pattern="[}]" pattern="[/]" pattern="[-]" pattern="[|]" pattern="[&&]" pattern="[!!]" pattern="[##]" pattern="[$$]" pattern="[%%]" pattern="[**]" pattern="[++]" pattern="[,,]" pattern="[..]" pattern="[::]" pattern="[;;]" pattern="[<<]" pattern="[==]" pattern="[>>]" pattern="[??]" pattern="[@@]" pattern="[``]" pattern="[~~]" pattern="[_^^]"抛出模式会导致
inputElement.validity.valid === true任何输入值,因此唯一的兼容性风险是以前会导致的某些值/模式组合inputElement.validity.valid === false现在会导致inputElement.validity.valid === true.
如果使先前有效的模式无效,其影响被认为很低,并且权衡允许使用更强大的模式。PR 中的示例:
Run Code Online (Sandbox Code Playgroud)pattern="[\p{ASCII_Hex_Digit}--[Ff]]" pattern="\p{RGI_Emoji}" pattern="[_\q{a|bc|def}]"
因此, HTML中的-in[\s-]需要进行转义:
:invalid {
background-color: red;
color: white;
}Run Code Online (Sandbox Code Playgroud)
<div class="formRow">
<label for="phone">Phone number</label>
<input name="custPhone" id="phone" type="tel" placeholder="(nnn) nnn-nnnn"
pattern="^\d{10}$|^(\(\d{3}\)\s*)?\d{3}[\s\-]?\d{4}$" >
</div>Run Code Online (Sandbox Code Playgroud)
相同的修复需要应用于现在在v(unicode 集)模式下无效的任何其他模式。
有关详细信息,请参阅使用 RegExp u 标志有效,但使用 v 标志无效