Шаблон C # / Regex работает при онлайн-тестировании, но не во время выполнения

#c# #regex

#c# #регулярное выражение

Вопрос:

Со следующим шаблоном регулярных выражений:

 (?<comment>(^#{2} [^rn] [s] )*)(?:^[(?:(?<hive>HK(?:LM|[DP]D|C[CUR]|U(SERS|SER|SR|S)))[:])?(?<name>[a-z0-9$][a-z0-9-_]{2,63})])(?<items>[Ss]*?)(?=n{2,})
  

Разбираем следующий текст:

 [HKLM:Connection]
   AuthKey = 0x8a79b42z67fct29b42e07b3fd78nc540
   Url = https://dev.somewebsite.com
   ApiPath = /api/

[HKLM:Settings]
   AutoMinimizeConsole = no
   StyleFile = Default
   PhoneNbrs = [ ]?[01]{0,3}[-. ]?[(]?[0-9][0-9][0-9][)]?[-. ]?[0-9][0-9][0-9][-. ]?[0-9][0-9][0-9][0-9]
   PostalCodes = [ABCEGHJKLMNPRSTVXYabceghjklmnprstvxy][0-9][ABCEGHJKLMNPRSTVWXYZabceghjklmnprstvwxyz][s.-]?[0-9][ABCEGHJKLMNPRSTVWXYZabceghjklmnprstvwxyz][0-9]

[HKLM:Font-Mapping]
   MonoSpaced = Courier New
   User1 = Software Tester 7
   User2 = Repetition Scrolling
   User3 = basis333

[HKLM:UserInterface]

[HKCU:UserInterface]

[HKCU:Credentials]
   Username =
   Password? =

  

При вводе в онлайн-тесты регулярных выражений результаты получаются такими, как ожидалось, но в коде совпадений не найдено.
Используемая здесь переменная «data» заполняется текстом, приведенным выше перед этим сегментом:

 public const string GROUP_PATTERN = @"(?<comment>(^#{2} [^rn] [s] )*)(?:^[(?:(?<hive>HK(?:LM|[DP]D|C[CUR]|U(SERS|SER|SR|S)))[:])?(?<name>[a-z0-9$][a-z0-9-_]{2,63})])(?<items>[Ss]*?)(?=n{2,})";
  
 Regex groupParser = new Regex(GROUP_PATTERN, RegexOptions.Compiled | RegexOptions.ExplicitCapture | RegexOptions.IgnoreCase | RegexOptions.Multiline);
MatchCollection matches = groupParser.Matches(data);
foreach (Match m in matches)
    this.Add(IniGroupItem.Parse(m.Value));
  

В начале ForEach совпадений ноль (должно быть шесть!)..

Поскольку шаблон работает на тестовых сайтах, но совсем не в c #, я не знаю, как выяснить, какие проблемы возникают с ним у компилятора. Есть идеи / предложения?

Комментарии:

1. Похоже, у вашего файла есть окончания CRLF, попробуйте заменить (?=n{2,}) на (?=(?:rn){2,})

2. doh ! — окей, я пошел и заменил «(?=n{2,})» на «(?=[r n]{3,})» и это работает так, как задумано! Если вы опубликуете это в качестве ответа, я отдам вам должное! 🙂

Ответ №1:

Окончания строк в большинстве онлайн-тестеров регулярных выражений являются только LF. Вы тестировали свой .NET regex в тестере регулярных выражений RegexStorm .NET вы бы быстрее определили проблему, поскольку его окончания строк — CRLF.

Итак, проблема в (?=n{2,}) том, что для этого требуется, чтобы новая строка повторялась 2 или более раз. Поскольку в реальных данных есть две или более последовательностей rn , вам нужно заменить эту часть шаблона на (?=(?:rn){2,}) .

Если вы говорите, что (?=[rn]{3,}) работает для вас, это означает, что вы хотите сопоставить местоположение, за которым следуют 3 или более символов LF или CR.

В смешанных случаях, если вы хотите сопоставить место, за которым следует 2 или более последовательностей перевода строки в формате CLF или LF, вы можете использовать (?=(?>rn?|n){2,}) .

Комментарии:

1. Как я упоминал ранее, я выбрал (?= [r n]{3,}), который не заботится о последовательности и не требует присутствия обоих символов. Есть ли причина, по которой этот способ уступает вашему?

2. @BrettLeuszler Все зависит от ваших требований. Если вы хотите сопоставить местоположение, за которым следуют 3 или более символов LF или CR, используйте (?=[rn]{3,}) . Если вы хотите сопоставить место, за которым следует 2 или более последовательностей переноса строки, (?=(?>rn?|n){2,}) является более точным

3. Меня беспокоит использование » r n» в качестве строгого литерала в том, что у меня были случаи, когда входящий текст имел порядок (досадно!) наоборот (LFCR вместо CRLF). С тех пор я предпочитаю «[r n]{2}» вместо строгого литерала » r n», вот почему я рефлексивно вернулся к этому шаблону.

4. Кроме того, также (смеется) — я преимущественно использую regex101.com для тестирования регулярных выражений в основном из-за большого объема диагностики, которую он предоставляет для реального углубления в синтаксис шаблона, и объема легкодоступной помощи, которую он предоставляет. Очевидно, однако, что в нем явно присутствует проблема, которую вы определили между CRLF и LF при разборе исходного текста, поэтому хорошо иметь другой ресурс для проверки!