2016-01-29 6 views
1

Если я создаю Regex на основе этой модели: @"[A-Za-z]+", делает множество, что соответствует изменению вообще, добавив RegOptions.IgnoreCase, если я уже использую RegOptions.CultureInvariant (из-за issues like this)? Я думаю, что это очевидное «нет, это просто избыточно и повторяемо». И в моих тестах это то, что я показал, но мне интересно, не хватает ли я чего-то из-за ошибки подтверждения.Понимание последствия CultureInvariant и IgnoreCase на [A-Za-Z]

Пожалуйста, исправьте меня, если я ошибаюсь в этом вопросе, но я считаю, что мне определенно нужно использовать CultureInvariant, хотя я также не знаю, какова будет культура. MSDN Reference

Примечание: Это не фактический образец, который мне нужно использовать, просто простейшая критическая его часть. Полный шаблон: @"[A-Za-z0-9\s!\\#$(),.:;[email protected]'\-{}|/&]+", если на самом деле есть странное поведение, окружающее символы, случай и культуру. Нет, я не создал шаблон, я просто его потребляю, не могу его изменить, и я понимаю, что | не нужен до /&.

Если бы я мог изменить шаблон ...

  1. шаблон "[a-z]" с обоими CultureInvariant и IgnoreCase будет функционально эквивалентно "[A-Za-z]" с использованием только CultureInvariant правильно?
  2. Предполагая, что № 1 является правильным, что было бы более эффективным и почему? Я бы предположил, что более короткая модель более эффективна для оценки, но я не знаю, как внутренние работы работают прямо сейчас, чтобы сказать это с большой уверенностью.
+1

'CultureInvariant' не влияет на' [A-Za-z] ', потому что турецкий i (или любые другие символы, относящиеся к культуре) не находится в указанном вами диапазоне. –

+0

Возможно, запустите цикл над всеми возможными символами 65536? Вы даже можете проверить все 2 последовательности символов. – usr

+1

Анекдотические доказательства, которые я обнаружил при исследовании моего ответа здесь: http://stackoverflow.com/questions/6004819/why-compiled-regex-performance-is-slower-than-intrepreted-regex/6005226#6005226 указывает, что '[A- Za-z] 'будет быстрее, чем использование' RegexOptions.IgnoreCase'. –

ответ

1

У меня возникло фундаментальное непонимание того, как все это работает. Я думаю, что это то, что бросает меня ...

Regex regex = new Regex("[A-Za-z]", RegexOptions.IgnoreCase); 

... вернется false для regex.IsMatch("ı"), но true для regex.IsMatch("İ"). Если я удалю IgnoreCase, он возвращает false для обоих, и если бы я использовал CultureInvariant (с или без IgnoreCase), он вернет false, и это в основном сводится к тому, что сказал Скотт Чемберлен в своем комментарии. Спасибо, Скотт.

В конце концов я хочу «Я» и «Я», чтобы как быть отвергнута, и я только что получил сам все обернулись, принося IgnoreCase в смесь, прежде чем я даже подумывал CultureInvariant. Если я опустил IgnoreCase и добавлю CultureInvariant, тогда я смогу сохранить шаблон как есть и сопоставить его с тем, что я хочу.

Если бы я смог изменить шаблон только на "[A-Z]", тогда я мог бы использовать оба флага и по-прежнему получать желаемое поведение. Но немного об изменении шаблона, и который был бы более эффективным, было просто любопытством. Я не хочу разбираться во всех проблемах, которые могут возникнуть в результате этой дискуссии, и о всех способах изменения шаблона. Моя забота была о культуре, нечувствительности к регистру, и этих двух RegexOptions.

Подводя итог, мне нужно сбросить IgnoreCase, а затем весь вопрос, окружающий культуру, исчезнет.Если образец был a-z или A-Z, и мне нужно использовать IgnoreCase, чтобы соответствовать верхним и нижним, то я бы потребности использовать CultureInvariant также.

2

С помощью этой программы мы можем проверить все возможные последовательности из двух букв:

static void Main() 
{ 
    var defaultRegexOptions = RegexOptions.CultureInvariant | RegexOptions.ExplicitCapture | RegexOptions.Singleline; 
    var regex1 = new Regex(@"^[A-Za-z]+$", defaultRegexOptions); 
    var regex2 = new Regex(@"^[A-Za-z]+$", defaultRegexOptions | RegexOptions.IgnoreCase); 

    ParallelEnumerable.Range(char.MinValue, char.MaxValue - char.MinValue + 1) 
     .ForAll(firstCharAsInt => 
     { 
      var buffer = new char[2]; 
      buffer[0] = (char)firstCharAsInt; 

      for (int i = char.MinValue; i <= char.MaxValue; i++) 
      { 
       buffer[1] = (char)i; 

       var str = new string(buffer); 

       if (regex1.IsMatch(str) != regex2.IsMatch(str)) 
        Console.WriteLine("dfjkgnearjkgh"); 
      } 
     }); 
} 

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

Программа занимает 20 минут.

К сожалению, этот ответ не дает никакого представления о , почему это так.

+1

+1 за усилия, и я понимаю, как много толкований моего вопроса может дать такой прагматичный ответ, и я также понимаю, что мой вопрос может быть сведен к простому «Нет» в ответ на «делает набор, который он соответствует изменению, добавляя IgnoreCase ", но, как вы сказали, это не дает понимания, и это действительно то, что я был после - понимание последствий использования этих флагов в сочетании с шаблоном, который уже не учитывает регистр в этом диапазоне символов внутри латинский алфавит. –

 Смежные вопросы

  • Нет связанных вопросов^_^