XSD "four alphanumerics, but not all digits" 的正则表达式?
XSD regex for "four alphanumerics, but not all digits"?
我正在尝试为必须包含四个字母数字(仅限大写)但不能包含全数字组合的元素编写 XML 架构数据类型。
换句话说,A-Z 或 0-9 中的四个序列,至少包含 A-Z 中的一个。
这是我遇到困难的后半部分,"at least one" 或 "but not"。
我想过 and/or 试过:
字符class减法(不过我觉得这里没办法定义"classes"?)
<!-- no example -->
合并 2 xs:restrictions
<xs:restriction>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="[0-9A-Z]{4}"/>
</xs:restriction>
</xs:simpleType>
<xs:pattern value="[^(\d\d\d\d)]"/>
</xs:restriction>
在两种数据类型中组合 2 xs:patterns
<xs:simpleType name="4alpha-at-least-one-letter">
<xs:restriction base="my-namespace:FourAlphanumericsType">
<xs:pattern value="[^(\d\d\d\d)]"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="FourAlphanumericsType">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9A-Z]{4}"/>
</xs:restriction>
</xs:simpleType>
我想这些都是死胡同,我要么在正则表达式世界中遗漏了一些东西,要么 XML 正则表达式可能不是执行此操作的最佳方法?
XML Schema regex不支持lookarounds,所以只能拼出regex:
<xs:pattern value="[A-Z][A-Z0-9]{3}|[A-Z0-9][A-Z][A-Z0-9]{2}|[A-Z0-9]{2}[A-Z][A-Z0-9]|[A-Z0-9]{3}[A-Z]"/>
参见regex demo。
如果您还需要匹配小写字母,请将a-z
添加到ech [...]
(字符class)中。
更新:不要错过。我会在这里留下我的答案,以了解它可能有的任何有用的花絮,但 sergioFC 是总体上最好的解决方案。
XSD 1.0
通过使用多个模式,可以比 Wiktor Stribiżew 的 (+1) 略微提高可读性:
<xs:simpleType name="AtLeastOneLetterInFourAlphaType">
<xs:restriction base="xs:string">
<xs:pattern value="[A-Z][A-Z0-9]{3}"/>
<xs:pattern value="[A-Z0-9][A-Z][A-Z0-9]{2}"/>
<xs:pattern value="[A-Z0-9]{2}[A-Z][A-Z0-9]"/>
<xs:pattern value="[A-Z0-9]{3}[A-Z]"/>
</xs:restriction>
</xs:simpleType>
(在XSD中,多个模式代表交替。)
XSD 1.1
XSD 1.1 的断言设施可以表达值不能是数字的约束,这有效地要求伙伴模式中表达的至少一个字符是非数字的:
<xs:simpleType name="AtLeastOneLetterInFourAlphaType">
<xs:restriction base="xs:string">
<xs:pattern value="[A-Z0-9]{4}"/>
<xs:assertion test="not($value castable as xs:integer)"/>
</xs:restriction>
</xs:simpleType>
鉴于长度是固定的,另一种简单的解决方案是结合xs:pattern和xs:length限制:
<xs:simpleType name="x">
<xs:restriction base="xs:string">
<xs:pattern value="[A-Z0-9]*[A-Z][A-Z0-9]*"/>
<xs:length value="4"/>
</xs:restriction>
</xs:simpleType>
我正在尝试为必须包含四个字母数字(仅限大写)但不能包含全数字组合的元素编写 XML 架构数据类型。
换句话说,A-Z 或 0-9 中的四个序列,至少包含 A-Z 中的一个。
这是我遇到困难的后半部分,"at least one" 或 "but not"。
我想过 and/or 试过:
字符class减法(不过我觉得这里没办法定义"classes"?)
<!-- no example -->
合并 2 xs:restrictions
<xs:restriction>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="[0-9A-Z]{4}"/>
</xs:restriction>
</xs:simpleType>
<xs:pattern value="[^(\d\d\d\d)]"/>
</xs:restriction>
在两种数据类型中组合 2 xs:patterns
<xs:simpleType name="4alpha-at-least-one-letter">
<xs:restriction base="my-namespace:FourAlphanumericsType">
<xs:pattern value="[^(\d\d\d\d)]"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="FourAlphanumericsType">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9A-Z]{4}"/>
</xs:restriction>
</xs:simpleType>
我想这些都是死胡同,我要么在正则表达式世界中遗漏了一些东西,要么 XML 正则表达式可能不是执行此操作的最佳方法?
XML Schema regex不支持lookarounds,所以只能拼出regex:
<xs:pattern value="[A-Z][A-Z0-9]{3}|[A-Z0-9][A-Z][A-Z0-9]{2}|[A-Z0-9]{2}[A-Z][A-Z0-9]|[A-Z0-9]{3}[A-Z]"/>
参见regex demo。
如果您还需要匹配小写字母,请将a-z
添加到ech [...]
(字符class)中。
更新:不要错过
XSD 1.0
通过使用多个模式,可以比 Wiktor Stribiżew 的
<xs:simpleType name="AtLeastOneLetterInFourAlphaType">
<xs:restriction base="xs:string">
<xs:pattern value="[A-Z][A-Z0-9]{3}"/>
<xs:pattern value="[A-Z0-9][A-Z][A-Z0-9]{2}"/>
<xs:pattern value="[A-Z0-9]{2}[A-Z][A-Z0-9]"/>
<xs:pattern value="[A-Z0-9]{3}[A-Z]"/>
</xs:restriction>
</xs:simpleType>
(在XSD中,多个模式代表交替。)
XSD 1.1
XSD 1.1 的断言设施可以表达值不能是数字的约束,这有效地要求伙伴模式中表达的至少一个字符是非数字的:
<xs:simpleType name="AtLeastOneLetterInFourAlphaType">
<xs:restriction base="xs:string">
<xs:pattern value="[A-Z0-9]{4}"/>
<xs:assertion test="not($value castable as xs:integer)"/>
</xs:restriction>
</xs:simpleType>
鉴于长度是固定的,另一种简单的解决方案是结合xs:pattern和xs:length限制:
<xs:simpleType name="x">
<xs:restriction base="xs:string">
<xs:pattern value="[A-Z0-9]*[A-Z][A-Z0-9]*"/>
<xs:length value="4"/>
</xs:restriction>
</xs:simpleType>