0

我在创建一个正则表达式以在 XML 模式中使用作为对字符串元素的限制时遇到了一点挑战。

挑战在于字符串(现在)可以包含以下值:

HASCALCULATOR, LISTUPDATENEEDED,READ ONLYMANDATORY.

每个值只能出现一次,并且可以是随机顺序。值用空格(空格)分隔。不需要所有值都存在。

有效字符串示例:

HASCALCULATOR LISTUPDATENEEDED READ ONLY MANDATORY
HASCALCULATOR READ ONLY
READ ONLY HASCALCULATOR
MANDATORY
<Blank streng>

无效字符串示例:

READ ONLY HASCALCULATOR READ ONLY
SOMETHING READ ONLY
READ ONLY SOMETHING HASCALCULATOR LISTUPDATENEEDED READ ONLY MANDATORY

我做了以下表达:

(HASCALCULATOR\s?|READONLY\s?|LISTUPDATENEEDED\s?|MANDATORY\s?){0,4}

但它并不涵盖所有情况。例如,它允许重复一个值。如果有人可以帮助我并提出更好的表达方式,我将不胜感激。请注意与 XML 模式中的 RegEx 表达式相关的限制,如下所述:http ://www.regular-expressions.info/xml.html

4

1 回答 1

0

你有几个选择。

(1) 您可以通过编写一个相当复杂的正则表达式来强制执行您描述的约束,如下所示:

  • 存在所有四个字符串的每个合法值都是序列(“HASCALCULATOR”、“READ ONLY”、“LISTUPDATENEEDED”、“MANDATORY”)的一些排列的串联。
  • 每个存在少于四个字符串的合法值都是一些排列连接的前缀。

因此,您可以通过计算四个字符串的 24 次排列,并将后缀设为可选来完整地写出正则表达式:

<xs:simpleType name="properties">
  <xs:restriction base="xs:string">
    <xs:whiteSpace value="collapse"/>
    <xs:pattern value="((HASCALCULATOR (LISTUPDATENEEDED 
      (READ ONLY (MANDATORY)?)?)?)|(HASCALCULATOR 
      (LISTUPDATENEEDED (MANDATORY (READ ONLY)?)?)?)|(HASCALCULATOR 
      (READ ONLY (LISTUPDATENEEDED (MANDATORY)?)?)?)|(HASCALCULATOR
      (READ ONLY (MANDATORY (LISTUPDATENEEDED)?)?)?)|(HASCALCULATOR 
      (MANDATORY (LISTUPDATENEEDED (READ ONLY)?)?)?)|(HASCALCULATOR 
      (MANDATORY (READ ONLY 
      (LISTUPDATENEEDED)?)?)?)|(LISTUPDATENEEDED (HASCALCULATOR 
      (READ ONLY (MANDATORY)?)?)?)|(LISTUPDATENEEDED (HASCALCULATOR 
      (MANDATORY (READ ONLY)?)?)?)|(LISTUPDATENEEDED (READ ONLY 
      (HASCALCULATOR (MANDATORY)?)?)?)|(LISTUPDATENEEDED (READ ONLY 
      (MANDATORY (HASCALCULATOR)?)?)?)|(LISTUPDATENEEDED (MANDATORY 
      (HASCALCULATOR (READ ONLY)?)?)?)|(LISTUPDATENEEDED (MANDATORY 
      (READ ONLY (HASCALCULATOR)?)?)?)|(READ ONLY (HASCALCULATOR 
      (LISTUPDATENEEDED (MANDATORY)?)?)?)|(READ ONLY (HASCALCULATOR 
      (MANDATORY (LISTUPDATENEEDED)?)?)?)|(READ ONLY 
      (LISTUPDATENEEDED (HASCALCULATOR (MANDATORY)?)?)?)|(READ ONLY 
      (LISTUPDATENEEDED (MANDATORY (HASCALCULATOR)?)?)?)|(READ ONLY 
      (MANDATORY (HASCALCULATOR (LISTUPDATENEEDED)?)?)?)|(READ ONLY 
      (MANDATORY (LISTUPDATENEEDED (HASCALCULATOR)?)?)?)|(MANDATORY 
      (HASCALCULATOR (LISTUPDATENEEDED (READ ONLY)?)?)?)|(MANDATORY 
      (HASCALCULATOR (READ ONLY (LISTUPDATENEEDED)?)?)?)|(MANDATORY 
      (LISTUPDATENEEDED (HASCALCULATOR (READ ONLY)?)?)?)|(MANDATORY 
      (LISTUPDATENEEDED (READ ONLY (HASCALCULATOR)?)?)?)|(MANDATORY 
      (READ ONLY (HASCALCULATOR (LISTUPDATENEEDED)?)?)?)|(MANDATORY 
      (READ ONLY (LISTUPDATENEEDED (HASCALCULATOR)?)?)?))?">
      <xs:annotation>
        <xs:documentation>
          The pattern here was calculated this way.
          1 Let A = "HASCALCULATOR", B = "LISTUPDATENEEDED", 
            C = "READ ONLY", and D = "MANDATORY".
          2 Calculate the permutations of the sequence (A,B,C,D). 
            A sequence with four members has 4! = 24 permutations: 
            (A,B,C,D), (A,B,D,C), (A,C,B,D), (A,C,D,B), ...
          3 From each permutation generate a regex of the form
            (s1 (s2 (s3 (s4)?)?)?)
          4 Join all of these in single optional choice.
        </xs:documentation>
      </xs:annotation>
    </xs:pattern>
  </xs:restriction>
</xs:simpleType>

(2) 通过左分解析取可以产生一个不太冗长的版本,这样一个结构就像

(A (B, (C, (D)?)?)?)
|(A (B, (D, (C)?)?)?) 
|(A (C, (B, (D)?)?)?)
|(A (C, (D, (B)?)?)?)

变成类似的东西

(A ((B ((C D?)|(D C?))? 
  | (C ((B D?)|(D B?))?)
  | (D ((B C?)|(C B?))?)))

(3) 你可以重新思考材料的表现形式。例如,您可以将四个字符串中的任何一个字符串的存在视为一个标志并忽略重复;这将使您绘制的图案可以正常工作。

(4) 您可以将标志表示为四个布尔属性,以便代替

<xs:element name="properties" type="tns:properties"/>
<!--* assumes the declaration for 'properties' type
    * given above *-->

你写这样的东西:

<xs:element name="properties">
  <xs:complexType>
    <xs:attribute name="has-calculator" type="xs:boolean"/>
    <xs:attribute name="mandatory" type="xs:boolean"/>
    <xs:attribute name="read-only" type="xs:boolean"/>
    <xs:attribute name="list-update-needed" type="xs:boolean"/>
  </xs:complexType>
</xs:element>

(5) 您可以将标志表示为空元素,它们通过发生来表示属性:

<xs:complexType name="empty">
  <xs:sequence/>
</xs:complexType>
<xs:element name="properties">
  <xs:complexType>
    <xs:all>
      <xs:element name="has-calculator" 
                  type="tns:empty" minOccurs="0"/>
      <xs:element name="mandatory" 
                  type="tns:empty" minOccurs="0"/>
      <xs:element name="read-only" 
                  type="tns:empty" minOccurs="0"/>
      <xs:element name="list-update-needed" 
                  type="tns:empty" minOccurs="0"/>
    </xs:all>
  </xs:complexType>
</xs:element>

我自己倾向于使用选项(5)。但是从问题的一般感觉,再加上全大写字符串,我猜您正在处理来自完善系统的输出,并且更改格式是不可行的。

于 2013-08-13T00:03:59.667 回答