不允许 XSD 正则表达式中的特定字符串

Not allowing a specific string in an XSD Regular expression

我正在尝试使用正则表达式验证受限字符串...

<xs:simpleType name="myStringType">
    <xs:restriction base="xs:string">
        <xs:pattern value="^urn:mystuff:v1:(ABC\.(?!Acme).\S+\.\S+\.a\d+\.v\d+|ABC\.Acme\.\S+\.a\d+\.\d+\.\d+)$"/>
    </xs:restriction>
</xs:simpleType>

如您所见,我尝试使用的正则表达式是

^urn:mystuff:v1:(ABC\.(?!Acme).\S+\.\S+\.a\d+\.v\d+|ABC\.Acme\.\S+\.a\d+\.\d+\.\d+)$

我想验证以下内容:

urn:mystuff:v1:ABC.Test.MyData.a1.v1
urn:mystuff:v1:ABC.Acme.MyData.a1.0.1

但我希望以下操作失败

urn:mystuff:v1:ABC.Acme.MyData.a1.v1

这似乎在 online regex tester 中工作正常,但是当我使用 Oxygen XML 编辑器时,出现以下错误。

 Pattern value '^urn:mystuff:v1:(ABC\.(?!Acme).\S+\.\S+\.a\d+\.v\d+|ABC\.Acme\.\S+\.a\d+\.\d+\.\d+)$' is not a valid regular expression. The reported error was: 'This expression is not supported in the current option setting.'.

表明 XSD 正则表达式不支持先行和后行,但问题与数字模式有关,因此在示例中采用了蛮力方法。这是可能的,因为可能性的子集非常有限。

当不允许的值是特定字符串时,如何处理?

附录: 请注意,此解决方案在字符串中的固定位置植入伪断言。
对于应该跨越整个字符串的断言的示例解决方案
看到这个问题 XML schema restriction pattern for not allowing specific string


edit : 正如评论中所指出的,使用 (..) 而不是 (?:..) 如果那是唯一的
支持的结构。
已更改!


这个系列(?!Acme)\S+\.可以用这个大系列代替:

([^A]\S*|A([^c.]\S*)?|Ac([^m.]\S*)?|Acm([^e.]\S*)?)\.

更大但应该涵盖所有情况并现在制作正则表达式:

urn:mystuff:v1:(ABC\.([^A]\S*|A([^c.]\S*)?|Ac([^m.]\S*)?|Acm([^e.]\S*)?)\.\S+\.a\d+\.v\d+|ABC\.Acme\.\S+\.a\d+\.\d+\.\d+)

https://regex101.com/r/qXv9HU/2

展开

 urn:mystuff:v1:
 (                             # (1 start)
      ABC \. 
      (                             # (2 start)
           [^A]  \S* 
        |  A 
           ( [^c.] \S* )?                # (3)
        |  Ac 
           ( [^m.] \S* )?                # (4)
        |  Acm  
           ( [^e.] \S* )?                # (5)
      )                             # (2 end)
      \. 
      \S+ \. a \d+ \. v \d+ 
   |  
      ABC \. Acme \. \S+ \. a \d+ \. \d+ \. \d+ 
 )                             # (1 end)

最简单的方法是在 the XML Schem specification:

中利用此规则

If multiple element information items appear as children of a <simpleType>, the values should be combined as if they appeared in a single regular expression as separate branches. Note: It is a consequence of the schema representation constraint Multiple patterns (§4.3.4.3) and of the rules for restriction that pattern facets specified on the same step in a type derivation are ORed together, while pattern facets specified on different steps of a type derivation are ANDed together.

与其尝试使用单个正则表达式匹配两个允许的模式,不如指定两个单独的模式方面。如果需要第三个、第四个 URN 模式,那也会更自然地扩展。

XSD 对它在正则表达式中接受的内容有一个特定的定义,并且它比许多其他正则表达式方言更具限制性。我认为设计者的意图是使用 "common subset" 流行的正则表达式方言,以便它可以在任何平台上轻松实现。您正在使用未在此子集中定义的 (?! ... )(?: ... ) 等结构。不幸的是,@x15 的回答也是如此。

告诉您为什么您的尝试行不通很容易,找到可行的替代方法则更难。我会选择简单的选项,即使用像 test="matches($value, XX) or matches($value, YY) and not(matches($value, ZZ))" 这样的 XSD 1.1 断言。使用纯 XSD 1.0 的解决方案可能是可行的,但我不能立即看到它。