我需要满足仅接受 MM/DD/YYYY 形式的值的要求。
根据我读到的内容:https://www.w3.org/TR/xmlschema11-2/#nt-dateRep 使用
<xs:simpleType name="DATE">
<xs:restriction base="xs:date"/>
</xs:simpleType>
不会工作,因为它的正则表达式显然不支持这种格式。
我找到并调整了这个格式:
^(?:(?:(?:0?[13578]|1[02])(\/)31)\1|(?:(?:0?[1,3-9]|1[0-2])(\/)(?:29|30)\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:0?2(\/)29\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:(?:0?[1-9])|(?:1[0-2]))(\/)(?:0?[1-9]|1\d|2[0-8])\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$
此表格:
\^\(\?:\(\?:\(\?:0\?\[13578\]\|1\[02\]\)\(\\/\)31\)\1\|\(\?:\(\?:0\?\[1,3-9\]\|1\[0-2\]\)\(\\/\)\(\?:29\|30\)\2\)\)\(\?:\(\?:1\[6-9\]\|\[2-9\]\d\)\?\d{2}\)$\|\^\(\?:0\?2\(\\/\)29\3\(\?:\(\?:\(\?:1\[6-9\]\|\[2-9\]\d\)\?\(\?:0\[48\]\|\[2468\]\[048\]\|\[13579\]\[26\]\)\|\(\?:\(\?:16\|\[2468\]\[048\]\|\[3579\]\[26\]\)00\)\)\)\)$\|\^\(\?:\(\?:0\?\[1-9\]\)\|\(\?:1\[0-2\]\)\)\(\\/\)\(\?:0\?\[1-9\]\|1\d\|2\[0-8\]\)\4\(\?:\(\?:1\[6-9\]\|\[2-9\]\d\)\?\d{2}\)$
现在我不再在 XML 编辑器中遇到无效的转义错误(使用 XML Spy),但我得到了这个:
invalid-escape: The given character escape is not recognized.
我已经根据这里的XML模式规范完成了转义: https://www.w3.org/TR/xmlschema-2/#regexs F.1.1 节有一个转义表。
任何人都可以帮忙解决这个问题吗?
谢谢!
如果您检查 XSD 正则表达式语法 resources,您会注意到不支持 非捕获组 (
(?:...)
),也不支持 反向引用(\n
之类要引用的实体)到使用捕获组捕获的文本,(...)
)。
由于唯一的分隔符是
/
,因此您可以完全摆脱反向引用。
使用
((((0?[13578]|1[02])/31)/|((0?[13-9]|1[0-2])/(29|30)/))((1[6-9]|[2-9]\d)?\d{2})|(0?2/29/(((1[6-9]|[2-9]\d)?(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))|(0?[1-9]|1[0-2])/(0?[1-9]|1\d|2[0-8])/(1[6-9]|[2-9]\d)?\d{2})
参见 这个正则表达式演示
请注意,根据。到正则表达式.info:
特别值得注意的是完全没有锚点,例如脱字符号和美元、单词边界和环视。 XML 模式始终隐式锚定整个正则表达式。正则表达式必须匹配整个元素,该元素才被视为有效。
因此,您不应在 XSD 正则表达式中使用
^
(字符串开头)和 $
(字符串结尾)。
/
符号在正则表达式风格中被转义,它是正则表达式分隔符,而在XSD正则表达式中,没有正则表达式分隔符(因为唯一的操作是匹配,并且没有修饰符:XML模式)不提供指定匹配模式的方法)。因此,不要在 XSD 正则表达式中转义
/
。
在线测试仪测试注意
如果您在 regex101.com 或类似站点进行测试,请注意,在大多数情况下,如果选择
/
作为正则表达式分隔符,则需要对其进行转义。完成测试后,您可以在 \
之前安全地删除 /
。
好的,所以你从这里开始(我将插入换行符以提高可读性):
^(?:(?:(?:0?[13578]|1[02])(\/)31)\1|(?:(?:0?[1,3-9]|1[0-2])(\/)
(?:29|30)\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$
|^(?:0?2(\/)29\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|
^(?:(?:0?[1-9])|(?:1[0-2]))(\/)(?:0?[1-9]|1\d|2[0-8])\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$
可怕的东西。现在,在 XSD 中:
(a) 没有
^
和 $
锚点,不需要它们(该模式是隐式锚定的)。所以把他们拿出来。您已通过将它们转义为 \^
和 \$
来回应,但这没有意义:您实际上并不希望在输入中使用扬抑符和美元符号。
(b) XSD 无法识别非捕获组
(?:xxxx)
。只需将它们替换为捕获组 - 也就是说,删除 ?:
再次,您已经逃脱了问号,这根本没有任何意义。
(c)
\d
可能应该是 [0-9]
,除非您确实想要匹配非 ASCII 数字(例如泰语或东阿拉伯数字)
(d) 斜杠 (
/
) 不需要转义,也确实无法转义。因此,请将 \/
替换为 /
。
(e) 我看到一些反向引用,
\1
、\2
、\4
。 XSD 正则表达式不允许反向引用。但据我所知,这个正则表达式中的反向引用没有任何用处。它们中的大多数似乎都是对一组(\/)
形式的反向引用,它只能匹配单个斜杠,因此反向引用\1
可以简单地替换为/
。也许它们是对某些早期形式的正则表达式的回归,允许替代分隔符但要求它们保持一致。
从您尝试解决这里的问题来看,在我看来您对正则表达式没有非常透彻的理解。我担心要让它发挥作用,你必须硬着头皮学习它是如何运作的;调试复杂的正则表达式很困难,并且您无法通过反复试验来获得正确的结果。