Как разобрать это? - PullRequest
       20

Как разобрать это?

1 голос
/ 27 октября 2009

Мне нужно разобрать строку, которая имеет следующую структуру

x: {a, b, c,}, y: {d, e, f} и т. Д.

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

411: {1,2,3}, 241: {4,1,2} и т. Д.

Забыл упомянуть: количество разделенных запятыми записей между {} не имеет верхнего предела, но должно иметь хотя бы одну запись.

  1. Мне нужно получить уникальный список числа перед:, в вышеуказанном случае 411241

Можно ли это сделать с помощью регулярных выражений и как?

Ответы [ 8 ]

8 голосов
/ 27 октября 2009

Regex:

(?<1>[\d]+):{(?<2>\d+),(?<3>\d+),(?<4>\d+)}

Для данных:

411:{1,2,3},241:{4,1,2},314:{5,6,7}

создаст следующие коллекции совпадений / групп:

Match 0
Group 0: 411:{1,2,3}
Group 1: 411
Group 2: 1
Group 3: 2
Group 4: 3

Match 1
Group 0: 241:{4,1,2}
Group 1: 241
Group 2: 4
Group 3: 1
Group 4: 2

Match 2
Group 0: 314:{5,6,7}
Group 1: 314
Group 2: 5
Group 3: 6
Group 4: 7

Вы можете использовать следующий код:

string expression = "(?<1>[\d]*):{(?<2>\d),(?<3>\d),(?<4>\d)}";
string input = "411:{1,2,3},241:{4,1,2},314:{5,6,7}";

Regex re = new Regex(expression, RegexOptions.IgnoreCase);

MatchCollection matches = re.Matches(input);

for (int i = 0; i < matches.Count; i++)
{
Match m = matches[i];
// for i==0
// m.groups[0] == 411:{1,2,3}
// m.groups[1] == 411
// m.groups[2] == 1
// m.groups[3] == 2
// m.groups[4] == 4
}

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

string expression = "(?<1>[\d]+):{(?<2>[\d,?]+)}";
string input = "411:{1,2,3,4,5},241:{4,1,234}";

Regex re = new Regex(expression, RegexOptions.IgnoreCase);

MatchCollection matches = re.Matches(input);

for (int i = 0; i < matches.Count; i++)
{
Match m = matches[i];
// for i==0
// m.groups[0] == "411:{1,2,3}"
// m.groups[1] == "411"
// m.groups[2] == "1,2,3"
int[] list = m.Groups[1].Split(",");
// now list is an array of what was between the curly braces for this match
}

Список совпадений для выше:

Match 0
Group 0: 411:{1,2,3,4,5}
Group 1: 411
Group 2: 1,2,3,4,5

Match 1
Group 0: 241:{4,1,234}
Group 1: 241
Group 2: 4,1,234
2 голосов
/ 27 октября 2009

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

1 голос
/ 27 октября 2009

Вот альтернатива без RegEx, которая будет работать быстрее.

Возвращает Dictionary<Double, List<Double>> ....

public Dictionary<double, List<double>> Example()
        {
            String[] aSeparators = {"{", "},", ",", "}"};
            String data = "411:{1,2,3},843:{6,5,4,3,2,1},241:{4,1,2}";
            String[] bases = data.Split(aSeparators, StringSplitOptions.RemoveEmptyEntries);
            Dictionary<double, List<double>> aDict = null;

            double aHeadValue = 0;
            List<Double> aList = null;
            foreach (var value in bases)
            {
                if (value.EndsWith(":"))
                {
                    if (aDict == null)
                        aDict = new Dictionary<double, List<double>>();
                    else
                        aDict.Add(aHeadValue, aList);
                    aHeadValue = Double.Parse(value.TrimEnd(':'));
                    aList = new List<Double>();
                }
                else
                {
                    aList.Add(Double.Parse(value));
                }
            }
            aDict.Add(aHeadValue, aList);
            return aDict;
        }
1 голос
/ 27 октября 2009

Вы работаете с JSON? Если это так, вы можете проверить класс JavaScriptSerializer на MSDN,

http://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.aspx

1 голос
/ 27 октября 2009

эта строка имеет формат json. так что вы можете использовать Json.Net , чтобы проанализировать его для вас

1 голос
/ 27 октября 2009

Если мы рассмотрим x: {a, b, c} как элемент, следующее даст вам список совпадений с двумя именованными группами: Outer и Inner. Внешнее существо x, Внутреннее существо a, b, c.

(?<outer>\d+):\{(?<inner>\d+(,\d+)*)\}

Обновление

Вот пример кода:

        String input = "411:{1,2,3},241:{4,1,2},45:{1},34:{1,34,234}";
        String expr = @"(?<outer>\d+):\{(?<inner>\d+(,\d+)*)\}";

        MatchCollection matches = Regex.Matches(input, expr);

        foreach (Match match in matches)
        {
            Console.WriteLine("Outer: {0} Inner: {1}", match.Groups["outer"].Value, match.Groups["inner"]);
        }
1 голос
/ 27 октября 2009

Я думаю, это может сработать, псевдокод

foreach match in Regex.Matches(yourInputString, "[0-9]{3}:\{[0-9,]\},")
    firstNumber = match.Value.Substring(0, 3)
    numbers() = match.Value.Substring(4, match.Value.Length - 5).Split(",")
next
0 голосов
/ 27 октября 2009

Первый достижим со следующим регулярным выражением:

\d*(?=:)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...