Regex 不允许在XSD正则表达式中使用特定字符串

Regex 不允许在XSD正则表达式中使用特定字符串,regex,xml,xsd,Regex,Xml,Xsd,我正在尝试使用正则表达式验证受限字符串 <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 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.Test.MyData.a1.v1
urn:mystuff:v1:ABC.Acme.MyData.a1.0.1
但是我希望下面的失败

urn:mystuff:v1:ABC.Acme.MyData.a1.v1
这在一个应用程序中似乎工作得很好,但当我使用OxygenXML编辑器时,会出现以下错误

 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正则表达式中不支持lookaheads和lookbehinds,但问题与数字模式有关,因此示例中采用了暴力方法。这是可能的,因为可能性非常有限


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

adendum:请注意,此解决方案在字符串中的固定位置植入伪断言。
有关应跨越整个字符串的断言的示例解决方案
看到这个问题了吗


编辑:如评论中所述,如果只有
(…)
,请使用
(?:…)
支持的构造。
变了


此系列
(?!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+)

扩大

 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)

最简单的方法是在以下方面利用此规则:

如果多个元素信息项显示为
的子项,则应将这些值组合起来,就像它们作为单独的分支出现在单个正则表达式中一样。 注意:这是模式表示约束多个模式(§4.3.4.3)和限制规则的结果,即在类型派生的同一步骤上指定的模式面被OR在一起,而在类型派生的不同步骤上指定的模式面被and在一起


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

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


告诉你为什么你的尝试不起作用很容易,找到一个可行的替代方案则更难。我会选择简单的选项,即使用XSD1.1断言,如
test=“matches($value,XX)或matches($value,YY)和not(matches($value,ZZ))”
。使用纯XSD 1.0的解决方案可能是可行的,但我无法立即看到它。

要澄清一点,这个序列中的点
(?!Acme)。\S+
是文字还是元字符?或者,这是一个不应该出现的打字错误吗?字面意思。这样的例子pattern@x15你删除了你的答案吗?这个关于正则表达式的特定问题非常复杂。我甚至不想去想它,虽然我有很多次。我认为自己是个专家。这个问题碰巧有个解决办法。其他问题有一些有用的小道消息,但并没有真正为这个问题提供一个可行的答案,因为它有自己独特的挑战。这可以处理和或,但不能立即提供一种处理和不处理的方法。进一步思考后,我相信我建议的方法适用于问题中描述的场景。字符串
urn:mystuff:v1:ABC.Acme.MyData.a1.v1
与两个正则表达式都不匹配,因此不需要“AND not”。除非我遗漏了什么。2个正则表达式中的一个在某个位置使用了断言
(?!Acme)
,但由于不支持的构造而出错。不需要,因为特定项不需要。所有这些条件加在一起必须都是真的(
urn:mystuff:v1:ABC\.\S+\.\S+\.a\d+\.v\d+
,而不是
urn:mystuff:v1:ABC\.Acme\S*.\S+\.a\d+\.v\d+
)或(
urn:mystuff:v1:ABC\.Acme\.\S+\.a\d+.\d+.\d+.\d+
)不幸的是
(?:)
也超出了XSD正则表达式的定义。
 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)