none
Парсинг... RRS feed

  • Вопрос

  • Входная строка: +CMGL: 1,"REC READ","6677","","15/12/09,11:02:51+12"

    Строки находятся в кавычках, блоки разделяются запятыми.

    Необходимо вытащить данные как первую единицу так и все строки (в кавычках).

    Как это сделать покрасивее? Желательно с примером.

    
    29 ноября 2016 г. 11:29

Ответы

  • Конечно, можно использовать Regex.Split

    using System.Text.RegularExpressions;
    var input = "+CMGL:1,\"REC READ\",\"6677\",\"\",\"15/12/09,11:02:51+12\"";
    var stringArray = Regex.Split(input, ",\"|\",\"|\"");

    Результат: string[6] { "+CMGL:1", "REC READ", "6677", "", "15/12/09,11:02:51+12", "" }

    Но я бы лучше сделал через Regex.Match:

    var match = Regex.Match(input, "^[+]CMGL:(?<value1>\\d+),\"(?<value2>[\\w\\s]+)\",\"(?<value3>\\d+)\",\"(?<value4>.*?)\",\"(?<value5>[\\d,:+/]+)\"$");
    
    if (match.Success)
    {
        Console.WriteLine($"value1:   {match.Groups["value1"]}");
        Console.WriteLine($"value2:   {match.Groups["value2"]}");
        Console.WriteLine($"value3:   {match.Groups["value3"]}");
        Console.WriteLine($"value4:   {match.Groups["value4"]}");
        Console.WriteLine($"value5:   {match.Groups["value5"]}");
    }
    else
    {
        Console.WriteLine("Нет совпадения");
    }

    (Регулярное выражение может быть не точным. Написано только для этого примера.)

    Результат:

    value1:   1
    value2:   REC READ
    value3:   6677
    value4:   
    value5:   15/12/09,11:02:51+12

    30 ноября 2016 г. 10:53

Все ответы

  • https://msdn.microsoft.com/en-us/library/system.string.split
    29 ноября 2016 г. 11:48
  • К сожалению split тут не покатит, так как последняя строка содержит запятую.
    29 ноября 2016 г. 14:27
  • В поисковике наберите "regex csv comma quotes". 

    Если строки всегда в кавычках и в них самих нет кавычек, то можно и String.Split, только не по запятой, а по кавычкам. Как не сложно видеть при этом выйдет такое:

    REC READ

    ,

    6677

    ,

    ,

    15/12/09,11:02:51+12

    Строки с запятыми просто выбрасываем.


    This posting is provided "AS IS" with no warranties, and confers no rights.

    29 ноября 2016 г. 16:50
    Модератор
  • Можно попробовать регулярные выражения.
    Но всё это обсуждение не имеет никакого практического смысла без понимания задачи. Пока что ясно, что вам необходимо анализировать какие-то логи. Судя по всему, это что-то связанное с GSM/SMS и пр. Вообще говоря, такие задачи многие люди уже решали и, возможно, вам нужно не изобретать свой плохой велосипед, а просто погуглить что-то вроде SMS PDU PARSING. И посмотреть на какую-нибудь SMSLib или что-то ещё.

    Если всё же очень хочется написать свой парсер, то стоит сформулировать нефункциональные требования. Если у вас там 100к сообщений в секунду, то могут быть нюансы

    29 ноября 2016 г. 17:45
  • Конечно, можно использовать Regex.Split

    using System.Text.RegularExpressions;
    var input = "+CMGL:1,\"REC READ\",\"6677\",\"\",\"15/12/09,11:02:51+12\"";
    var stringArray = Regex.Split(input, ",\"|\",\"|\"");

    Результат: string[6] { "+CMGL:1", "REC READ", "6677", "", "15/12/09,11:02:51+12", "" }

    Но я бы лучше сделал через Regex.Match:

    var match = Regex.Match(input, "^[+]CMGL:(?<value1>\\d+),\"(?<value2>[\\w\\s]+)\",\"(?<value3>\\d+)\",\"(?<value4>.*?)\",\"(?<value5>[\\d,:+/]+)\"$");
    
    if (match.Success)
    {
        Console.WriteLine($"value1:   {match.Groups["value1"]}");
        Console.WriteLine($"value2:   {match.Groups["value2"]}");
        Console.WriteLine($"value3:   {match.Groups["value3"]}");
        Console.WriteLine($"value4:   {match.Groups["value4"]}");
        Console.WriteLine($"value5:   {match.Groups["value5"]}");
    }
    else
    {
        Console.WriteLine("Нет совпадения");
    }

    (Регулярное выражение может быть не точным. Написано только для этого примера.)

    Результат:

    value1:   1
    value2:   REC READ
    value3:   6677
    value4:   
    value5:   15/12/09,11:02:51+12

    30 ноября 2016 г. 10:53
  • Очень хорошо все пошло. Спасибо!

    Я изначально пытался сделать через Regex, но вот с паттернами у меня ничего не вышло. Как вы такой сложный паттерн написали? Может есть ли какое - нибудь средство?

    PS: В общем это заголовок SMS сообщения, отсылаемый Модемом SIM900

    value1:   Индекс по порядку;
    value2:   Статус прочтения;
    value3:   Номер отправителя;
    value4:   Всегда пустое;
    value5:   Дата и время получения;

    5 декабря 2016 г. 10:20
  • Как вы такой сложный паттерн написали? Может есть ли какое - нибудь средство?

    Паттерн совсем не сложный. Состоит из четырех групп (?<groupName>...), каждая из которых берет значение, которому соответствует. Все остальное - это по сути, элементы исходной строки, которые не попадают в выборку, но должны быть обязательно в исходной строке.

    Специальных средств не использую. Пользуюсь только стандартным полем поиска по странице в VisualStudio (там есть опция поиска с помощью регулярных выражений).

    Чтобы научится уверенно работать с регулярными выражениями советую прочитать книгу "Регулярные выражения, 3-е издание, Джеффри Фридл, 2008". Книга старая, но актуальная. 

    Справка на msdn тоже может сильно помочь: https://msdn.microsoft.com/ru-ru/library/az24scfc(v=vs.110).aspx

    6 декабря 2016 г. 13:50