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

时间:2016-01-08 22:04:16

标签: regex xsd

我想使用正则表达式查看数字是否不以特定值开头。 我的模式应接受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>

但它似乎不适用于XSD模式

2 个答案:

答案 0 :(得分:3)

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

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

请参阅this

由于默认情况下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的整数。

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

答案 1 :(得分:1)

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

在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 来允许simpleType中的多个值范围:

<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,因此根据情况限制值可能比限制文字更加可维护。

此外,请注意,您可以在xs:restriction中使用多个 xs:pattern ,并且simpleType必须至少匹配其中一个才有效。因此,您可以通过多种方式使用stribizhev答案:单个模式中的完整正则表达式,或者在多个xs:模式中分割,如果您需要它,或者您可以更清楚地看到它。