Шаблон регулярного выражения XSD в .Net вызывает зависание приложения - PullRequest
4 голосов
/ 27 февраля 2010

Время обработки удваивается, когда «Y» идет вправо. Кто-нибудь может сказать мне, почему? Как решить эту проблему?

В базе данных хранится много больших идентификаторов, которые нельзя изменить, поэтому я не могу слишком сильно ограничить размер.

using System;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Schema;

namespace TestRegex
{
 class Program
 {
  static void Main(string[] args)
  {

   DateTime start = DateTime.Now;

   /******************************************
    *  ID to validate
    ******************************************/
   //string id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; // Ok: Fast
     string id = "xxxxxxxxxxxxxxxxxxxxxYxxxxxxx"; // Invalid: Slow
   //string id = "xxxxxxxxxxxxxxxxxxxxxxYxxxxxx"; // Invalid: Slower
   //string id = "xxxxxxxxxxxxxxxxxxxxxxxYxxxxx"; // Invalid: Very slow
   //string id = "xxxxxxxxxxxxxxxxxxxxxxxxYxxxx"; // Invalid: Very very slow

   /******************************************
    *  XML to validate
    ******************************************/  
   XmlDocument doc = new XmlDocument();
   doc.LoadXml("<root id='" + id + "'></root>");

   /******************************************
    *  XSD validator
    ******************************************/
   string xsl =
@"
<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'
           elementFormDefault='unqualified'
           attributeFormDefault='unqualified'>

 <xs:simpleType name='id'>
        <xs:restriction base='xs:string'>
            <xs:pattern value='^([a-z_]+[0-9]*)+' />
        </xs:restriction>
 </xs:simpleType>

    <xs:element name='root'>
        <xs:complexType>
            <xs:attribute name='id' use='required' type='id' />
  </xs:complexType>
 </xs:element>
</xs:schema>
";

   /******************************************
    *  Adds XSD to XML and validates it
    ******************************************/
   XmlTextReader reader = new XmlTextReader(
    new MemoryStream(ASCIIEncoding.Default.GetBytes(xsl)));

   XmlSchema schema = XmlSchema.Read(reader, new ValidationEventHandler(Validate));
   doc.Schemas.Add(schema);
   doc.Validate(new ValidationEventHandler(Validate));


   /******************************************
    *  Performance results
    ******************************************/
   Console.WriteLine(id.Length + " = " + (DateTime.Now - start).TotalSeconds);
   Console.Read();
  }

  private static void Validate(object o, ValidationEventArgs args)
  {
   if (args.Exception != null)
   {
    Console.WriteLine(args.Exception);
   }
  }
 }
}

Ответы [ 2 ]

2 голосов
/ 27 февраля 2010

Решено!

Регулярное выражение ^([a-z_][a-z_0-9]*) имеет такое же поведение и очень быстро.

2 голосов
/ 27 февраля 2010

Это похоже на случай катастрофического возврата .
Ваше регулярное выражение кажется слишком сложным. Если я правильно читаю, он принимает строчные и цифры, когда первая буква не является цифрой. Вы можете переписать его как:

^[a-z_]\w*
...