Malindor Ответов: 2

Используя регулярные выражения C#, есть ли способ получить текст, соответствующий подстановочному знаку


Я создаю анализатор ошибок для утилиты среднего уровня. Утилита принимает некоторый XML, манипулирует им в зависимости от содержимого и затем передает его в другую службу. Новый парсер ошибок будет выполнять проверку схемы и данных по входящему XML. Многие из ошибок, которые мы получаем, являются недостающими элементами. Сообщения об ошибках, такие как:

Строка: 1, Позиция 2: "не удалось найти информацию о схеме для элемента 'HearingDocExtract'."
Строка: 1, позиция 3288: "элемент ' DocumentCopy' не объявлен."
Строка: 1, позиция 3301: "не удалось найти информацию о схеме для атрибута 'DocumentID'."

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

Что я уже пробовал:

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

2 Ответов

Рейтинг:
7

OriginalGriff

Если ты имеешь в виду HearingDocExtract, DocumentCopy, и DocumentID Тогда это будет сделано:

(['])(?:(?=(\\?))\2.)*?\1

using System.Text.RegularExpressions;

/// <summary>
///  Regular expression built for C# on: Wed, May 9, 2018, 05:43:42 PM
///  Using Expresso Version: 3.0.4750, http://www.ultrapico.com
///  
///  A description of the regular expression:
///  
///  [1]: A numbered capture group. [[']]
///      Any character in this class: [']
///  Match expression but don't capture it. [(?=(\\?))\2.], any number of repetitions, as few as possible
///      (?=(\\?))\2.
///          Match a suffix but exclude it from the capture. [(\\?)]
///              [2]: A numbered capture group. [\\?]
///                  Literal \, zero or one repetitions
///          Backreference to capture number: 2
///          Any character
///  Backreference to capture number: 1
///  
///
/// </summary>
public static Regex regex = new Regex(
      "(['])(?:(?=(\\\\?))\\2.)*?\\1",
    RegexOptions.Multiline
    | RegexOptions.Singleline
    | RegexOptions.CultureInvariant
    | RegexOptions.Compiled
    );
// Capture all Matches in the InputText
MatchCollection ms = regex.Matches(InputText);

Если вы хотите использовать регулярные выражения, то получите копию Экспрессо[^] - это бесплатно, и он проверяет и генерирует регулярные выражения.


Malindor

Даже не думал о том, чтобы ударить по одиночным кавычкам. Наверное, я слишком долго на это смотрел. Это может сработать не во всех случаях, но должно сработать для большинства из них. Спасибо и за то, что предупредили об экспрессо!!

OriginalGriff

Всегда пожалуйста!

BillWoodruff

+5 и пусть ваша кошка укусит вас !

OriginalGriff

Не давайте ему никаких идей! Он уже регулярно бьет меня по ногам.

Рейтинг:
1

RickZeeland

Вот хороший класс расширения, который сделает поиск регулярных выражений намного проще: Я не люблю регулярные выражения...[^]
Вы можете выполнить поиск с помощью подстановочного знака типа*, и результат будет содержать найденную строку.

Я немного изменил его, так что * также включает пробелы в результат, и пользователям не нужно использовать %:

static Regex GetRegex(string searchPattern)
        {
            return new Regex(searchPattern
                    .Replace("\\", "\\\\")
                    .Replace(".", "\\.")
                    .Replace("{", "\\{")
                    .Replace("}", "\\}")
                    .Replace("[", "\\[")
                    .Replace("]", "\\]")
                    .Replace("+", "\\+")
                    .Replace("$", "\\$")
                    .Replace(" ", "\\s")
                    .Replace("#", "[0-9]")
                    .Replace("?", ".")
                    //.Replace("*", "\\w*")     // word only, no whitespace
                    .Replace("*", ".*")
                    .Replace("%", ".*")
                    , RegexOptions.IgnoreCase);
        }


Malindor

Спасибо за функцию и ссылку на статью! Жаль, что я не сделал этого раньше.

BillWoodruff

+5 ценится ... Мне не нравится регулярное выражение как способ избежать чувства неполноценности по сравнению с другими программистами здесь, которые используют его так мастерски :) Конечно, я предполагаю, что вам это не нравится по гораздо более логичной причине !

RickZeeland

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