XSD 接受不以特定值开头的 5 个数字的模式

XSD pattern that accept 5 number which does not begin with specific values

我想使用正则表达式来查看数字是否不以特定值开头。 我的模式应该接受 01000 和 98899 之间的所有数字,除了那些以 977,978,979,981,982,983,984,985 开头的数字 我试过这个:

<xsd:simpleType name="CodeType">
    <xsd:restriction base="xsd:integer">
        <xsd:pattern value="(?!(977|978|979|981|982|983|984|985))\d{5}" />
        <xsd:minInclusive value="1000" />
        <xsd:maxInclusive value="98899" />
    </xsd:restriction>
</xsd:simpleType>

但它似乎对 int XSD 模式不起作用

请注意 XSD 模式不支持环视。因此,您必须将模式展开为

([0-8][0-9]{4}|97[0-6][0-9]{2}|98[06-9][0-9]{2}|9[0-69][0-9]{3})

regex demo

由于 XSD 模式默认锚定,我们不应该在两侧使用 ^$ 并且为了避免反斜杠问题,我建议替换 \d[0-9] (它还会使模式匹配普通数字而不是所有 Unicode 数字)。

此处所有选项都匹配5位数字。

  • [0-8][0-9]{4} - 所有以 00000 开头到 89999
  • 的整数
  • 97[0-6][0-9]{2} - 从 9700097699
  • 的整数
  • 98[06-9][0-9]{2} - 从 9800098999 的整数,不包括不需要的整数(白名单方法)
  • 9[0-69][0-9]{3} - 从 90000969999900099999.
  • 的整数

您在代码中使用的限制进一步限制了正则表达式。

我真的很喜欢,但是我想提出两个不同的想法。

在 XSD 1.1 中,您可以使用 xs:assertion 来测试某些值不以其他值开头:

    <xsd:simpleType name="CodeType">
        <xsd:restriction base="xsd:integer">
            <xsd:minInclusive value="1000" />
            <xsd:maxInclusive value="98899" />
            <xsd:assertion test="every $notAllowedPrefix in ('977','978','979','981','982','983','984','985') satisfies
                not(starts-with(string($value), $notAllowedPrefix))"/>
        </xsd:restriction>
    </xsd:simpleType>

在每个 XSD 版本中,您可以使用 xs:union 允许在一个简单类型中使用多个值范围:

<xsd:simpleType name="CodeType">
    <xsd:union>
        <!-- From 1000 to 97699 -->
        <xsd:simpleType>
            <xsd:restriction base="xsd:integer">
                <xsd:minInclusive value="1000" />
                <xsd:maxInclusive value="97699" />
            </xsd:restriction>
        </xsd:simpleType>
        <!-- From 98000 to 98199 -->
        <xsd:simpleType>
            <xsd:restriction base="xsd:integer">
                <xsd:minInclusive value="98000" />
                <xsd:maxInclusive value="98199" />
            </xsd:restriction>
        </xsd:simpleType>
        <!-- From 98600 to 98999 -->
        <xsd:simpleType>
            <xsd:restriction base="xsd:integer">
                <xsd:minInclusive value="98600" />
                <xsd:maxInclusive value="98999" />
            </xsd:restriction>
        </xsd:simpleType>            
    </xsd:union>
</xsd:simpleType>

请注意,整数值可以使用不同的文字表示,例如:1000=01000。我的解决方案可以限制值(它允许 1000、01000、00001000 等),而使用模式限制文字值。我的想法允许 9700 和 09700,而 stribizhev 解决方案只允许 09700 而不是 9700。如果你使用浮点数,你也可以使用 1000=01000=1e3=1E3 所以限制值可能比限制 literales 更容易维护,具体取决于情况。

另外注意,xs:restriction里面可以使用多个xs:pattern,simpleType必须至少匹配其中一个才有效。因此,您可以通过多种方式使用 stribizhev 答案:单个模式中的完整正则表达式或拆分成多个 xs:pattern,如果您想要它,或者您以这种方式看得更清楚。