如何在 XSD 模式中正确转义正则表达式模式?
How to properly escape Regular Expression pattern in XSD schema?
我需要满足只接受 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)|(?:(?:0?[1,3-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})$
到这个表格:
\^\(\?:\(\?:\(\?:0\?\[13578\]\|1\[02\]\)\(\/\)31\)\|\(\?:\(\?:0\?\[1,3-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}\)$
现在我在 XML 编辑器(使用 XML Spy)中不再遇到无效的转义错误,但我得到了这个:
invalid-escape: The given character escape is not recognized.
我已经根据这里的 XML 模式规范完成了转义:
https://www.w3.org/TR/xmlschema-2/#regexs F.1.1节有转义table.
任何人都可以帮助解决这个问题吗?
谢谢!
好的,所以你从这里开始(我将插入换行符以提高可读性):
^(?:(?:(?:0?[13578]|1[02])(\/)31)|(?:(?:0?[1,3-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})$
可怕的东西。现在,在 XSD:
(a) 没有 ^
和 $
锚点,不需要它们(模式是隐式锚定的)。所以带他们出去。您通过将它们转义为 \^
和 $
来做出响应,但这没有意义:您实际上不需要输入中的抑扬符和美元符号。
(b) XSD 无法识别非捕获组 (?:xxxx)
。只需将它们替换为捕获组 - 即删除 ?:
同样,您已经转义了问号,这根本没有任何意义。
(c) \d
可能应该是 [0-9]
,除非你真的想匹配非 ASCII 数字(例如泰语或东阿拉伯数字)
(d) Slash(/
)不需要转义,也确实不能转义。所以将 \/
替换为 /
.
(e) 我看到一些反向引用,</code>、<code>
、</code>。 XSD 正则表达式不允许反向引用。但据我所知,此正则表达式中的反向引用没有任何用处。它们中的大多数似乎是对一组只能匹配单个斜杠的 <code>(\/)
形式的反向引用,因此反向引用 </code> 可以简单地替换为 <code>/
。也许它们是对某些早期形式的正则表达式的倒退,该正则表达式允许替代定界符但要求它们保持一致。
从您尝试解决此处的问题来看,在我看来,您对正则表达式的理解不是很透彻。我担心要使它正常工作,您将不得不硬着头皮学习它是如何工作的;调试复杂的正则表达式很困难,你不会通过反复试验得到正确的答案。
如果您检查 XSD 正则表达式语法 resources, you will notice that there is no support for non-capturing groups ((?:...)
), nor backreferences(\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})
请注意,acc。到 regular-expressions.info:
Particularly noteworthy is the complete absence of anchors like the caret and dollar, word boundaries, and lookaround. XML schema always implicitly anchors the entire regular expression. The regex must match the whole element for the element to be considered valid.
因此,您不应在 XSD 正则表达式中使用 ^
(字符串开头)和 $
(字符串结尾)。
/
符号在正则表达式风格中被转义,它是 正则表达式定界符 ,而在 XSD 正则表达式中,没有正则表达式定界符(如唯一的动作是 匹配 ,并且没有修饰符:XML schemas do not provide a way to specify matching modes)。因此,不要在 XSD 正则表达式 中转义 /
。
在在线测试人员处测试注意
如果您在 regex101.com 或类似站点进行测试,请注意,在大多数情况下,如果 /
被选为正则表达式分隔符,您需要对其进行转义。完成测试后,您可以安全地删除 /
之前的 \
。
我需要满足只接受 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)|(?:(?:0?[1,3-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})$
到这个表格:
\^\(\?:\(\?:\(\?:0\?\[13578\]\|1\[02\]\)\(\/\)31\)\|\(\?:\(\?:0\?\[1,3-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}\)$
现在我在 XML 编辑器(使用 XML Spy)中不再遇到无效的转义错误,但我得到了这个:
invalid-escape: The given character escape is not recognized.
我已经根据这里的 XML 模式规范完成了转义: https://www.w3.org/TR/xmlschema-2/#regexs F.1.1节有转义table.
任何人都可以帮助解决这个问题吗?
谢谢!
好的,所以你从这里开始(我将插入换行符以提高可读性):
^(?:(?:(?:0?[13578]|1[02])(\/)31)|(?:(?:0?[1,3-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})$
可怕的东西。现在,在 XSD:
(a) 没有 ^
和 $
锚点,不需要它们(模式是隐式锚定的)。所以带他们出去。您通过将它们转义为 \^
和 $
来做出响应,但这没有意义:您实际上不需要输入中的抑扬符和美元符号。
(b) XSD 无法识别非捕获组 (?:xxxx)
。只需将它们替换为捕获组 - 即删除 ?:
同样,您已经转义了问号,这根本没有任何意义。
(c) \d
可能应该是 [0-9]
,除非你真的想匹配非 ASCII 数字(例如泰语或东阿拉伯数字)
(d) Slash(/
)不需要转义,也确实不能转义。所以将 \/
替换为 /
.
(e) 我看到一些反向引用,</code>、<code>
、</code>。 XSD 正则表达式不允许反向引用。但据我所知,此正则表达式中的反向引用没有任何用处。它们中的大多数似乎是对一组只能匹配单个斜杠的 <code>(\/)
形式的反向引用,因此反向引用 </code> 可以简单地替换为 <code>/
。也许它们是对某些早期形式的正则表达式的倒退,该正则表达式允许替代定界符但要求它们保持一致。
从您尝试解决此处的问题来看,在我看来,您对正则表达式的理解不是很透彻。我担心要使它正常工作,您将不得不硬着头皮学习它是如何工作的;调试复杂的正则表达式很困难,你不会通过反复试验得到正确的答案。
如果您检查 XSD 正则表达式语法 resources, you will notice that there is no support for non-capturing groups ((?:...)
), nor backreferences(\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})
请注意,acc。到 regular-expressions.info:
Particularly noteworthy is the complete absence of anchors like the caret and dollar, word boundaries, and lookaround. XML schema always implicitly anchors the entire regular expression. The regex must match the whole element for the element to be considered valid.
因此,您不应在 XSD 正则表达式中使用 ^
(字符串开头)和 $
(字符串结尾)。
/
符号在正则表达式风格中被转义,它是 正则表达式定界符 ,而在 XSD 正则表达式中,没有正则表达式定界符(如唯一的动作是 匹配 ,并且没有修饰符:XML schemas do not provide a way to specify matching modes)。因此,不要在 XSD 正则表达式 中转义 /
。
在在线测试人员处测试注意
如果您在 regex101.com 或类似站点进行测试,请注意,在大多数情况下,如果 /
被选为正则表达式分隔符,您需要对其进行转义。完成测试后,您可以安全地删除 /
之前的 \
。