Есть ли в C # встроенная поддержка парсинга строк с номерами страниц? - PullRequest
19 голосов
/ 02 сентября 2008

Есть ли в C # встроенная поддержка парсинга строк номеров страниц? Под номерами страниц я подразумеваю формат, который вы можете ввести в диалог печати, который представляет собой смесь запятой и тире.

Примерно так:

1,3,5-10,12

Что было бы действительно хорошо, так это решение, которое вернуло мне какой-то список всех номеров страниц, представленных строкой. В приведенном выше примере было бы неплохо получить список, подобный этому:

1,3,5,6,7,8,9,10,12

Я просто хочу не кататься, если есть простой способ сделать это.

Ответы [ 11 ]

0 голосов
/ 15 октября 2008

Вот немного измененная версия кода lassevk, который обрабатывает строку. Операция Split внутри соответствия Regex. Он написан как метод расширения, и вы легко справитесь с проблемой дубликатов, используя расширение Disinct () из LINQ.

    /// <summary>
    /// Parses a string representing a range of values into a sequence of integers.
    /// </summary>
    /// <param name="s">String to parse</param>
    /// <param name="minValue">Minimum value for open range specifier</param>
    /// <param name="maxValue">Maximum value for open range specifier</param>
    /// <returns>An enumerable sequence of integers</returns>
    /// <remarks>
    /// The range is specified as a string in the following forms or combination thereof:
    /// 5           single value
    /// 1,2,3,4,5   sequence of values
    /// 1-5         closed range
    /// -5          open range (converted to a sequence from minValue to 5)
    /// 1-          open range (converted to a sequence from 1 to maxValue)
    /// 
    /// The value delimiter can be either ',' or ';' and the range separator can be
    /// either '-' or ':'. Whitespace is permitted at any point in the input.
    /// 
    /// Any elements of the sequence that contain non-digit, non-whitespace, or non-separator
    /// characters or that are empty are ignored and not returned in the output sequence.
    /// </remarks>
    public static IEnumerable<int> ParseRange2(this string s, int minValue, int maxValue) {
        const string pattern = @"(?:^|(?<=[,;]))                      # match must begin with start of string or delim, where delim is , or ;
                                 \s*(                                 # leading whitespace
                                 (?<from>\d*)\s*(?:-|:)\s*(?<to>\d+)  # capture 'from <sep> to' or '<sep> to', where <sep> is - or :
                                 |                                    # or
                                 (?<from>\d+)\s*(?:-|:)\s*(?<to>\d*)  # capture 'from <sep> to' or 'from <sep>', where <sep> is - or :
                                 |                                    # or
                                 (?<num>\d+)                          # capture lone number
                                 )\s*                                 # trailing whitespace
                                 (?:(?=[,;\b])|$)                     # match must end with end of string or delim, where delim is , or ;";

        Regex regx = new Regex(pattern, RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled);

        foreach (Match m in regx.Matches(s)) {
            Group gpNum = m.Groups["num"];
            if (gpNum.Success) {
                yield return int.Parse(gpNum.Value);

            } else {
                Group gpFrom = m.Groups["from"];
                Group gpTo = m.Groups["to"];
                if (gpFrom.Success || gpTo.Success) {
                    int from = (gpFrom.Success && gpFrom.Value.Length > 0 ? int.Parse(gpFrom.Value) : minValue);
                    int to = (gpTo.Success && gpTo.Value.Length > 0 ? int.Parse(gpTo.Value) : maxValue);

                    for (int i = from; i <= to; i++) {
                        yield return i;
                    }
                }
            }
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...