Я работаю с XSD, и у меня есть доступ к шаблону из XSD в виде строки. Пример:
<xsd:pattern value="[0-9]{8}"/>
дает мне строку С#
string pattern = "[0-9]{8}";
Из строки шаблона, которую я получаю из XSD (которая может быть любой допустимой строкой XSD), я пытаюсь выработать максимально возможную длину, которую может содержать содержимое поля в XML.
В этом тривиальном примере, очевидно, 8 - я мог бы понять это, проверив {n} и предполагая, что длина. В других шаблонах я также мог проверить * или + и предположить неограниченное - но я ищу более общий подход, который можно использовать для этого.
Обратите внимание, что строка шаблона не гарантируется совместимость с классами.Net Regex.
У меня также есть доступ к классу XmlSchemaPatternFacet, который я использую для синтаксического анализа XSD, если это поможет.
Спасибо за любую помощь, которую вы можете дать
Вы почти наверняка должны проанализировать регулярное выражение, чтобы достичь этого. Например, вы можете взять парсер регулярных выражений с открытым исходным кодом в Saxon (который реализует правильный диалект regex). Это создает дерево подвыражений, и вы можете добавить метод для вычисления максимальной длины соответствия для каждого узла в дереве. Класс Operation
, представляющий узел в дереве, уже (в 9.6) имеет методы getMatchLength()
и getMinimumMatchLength()
, и было бы достаточно просто добавить getMaximumMatchLength()
который работает одинаково.
С этими определениями:
<xs:simpleType name="ST_exactly8digitsString">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9]{8}"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="ST_upto8digitsString">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9]{0,8}"/>
</xs:restriction>
</xs:simpleType>
все они подтвердят:
<upto8digitsString>12345678</upto8digitsString>
<upto8digitsString>12345</upto8digitsString>
<exactly8digitsString>12345678</exactly8digitsString>
это не будет:
<exactly8digitsString>12345</exactly8digitsString>
<upto8digitsString>123456789</upto8digitsString>
Хотя, я думаю, вы ищите:
<xs:simpleType name="ST_anyNoDigitsString">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9]*"/>
</xs:restriction>
</xs:simpleType>
Все они соответствуют:
<anyNoDigitsString>12345678900000000</anyNoDigitsString>
<anyNoDigitsString>88</anyNoDigitsString>
<anyNoDigitsString></anyNoDigitsString>
<anyNoDigitsString>0</anyNoDigitsString>
По сравнению с другими регулярными выражениями.Net регулярные выражения схемы XML ограничены в функциях. Поскольку они используются только для проверки того, соответствует ли весь элемент шаблону или нет. Afaik, допускаются только жадные кванторы ?, *, +
И {n,m}
.
XmlSchemaPatternFacet
для определения длины, с недостатками imho. Просто проверьте XML с некоторыми шаблонами. Если это работает, ожидания оправдались ... Бесполезно делать какие-то выводы по длине паттерна.
Я предполагаю, что это будет очень сложно. Со встроенными скобками вам придется рекурсивно искать длину шаблона.
Изменение: я нашел https://github.com/moodmosaic/Fare, который соответствует вашим требованиям.
var regex = @"((mailto\:|(news|(ht|f)tp(s?))\://){1}\S+)";
var xeger = new Xeger(regex);
var result = Regex.IsMatch(xeger.Generate(), regex);
Также я не уверен, что найдет максимально возможный ответ, но это может быть началом.