Мне нужно преобразовать строку, например,
"[1,2,3,4][5,6,7,8]"
на группы целых чисел, скорректированных так, чтобы они основывались на нуле, а не на единице:
{0,1,2,3} {4,5,6,7}
Также применяются следующие правила:
- Строка должна содержать хотя бы 1 группу чисел, заключенных в квадратные скобки.
- В каждой группе должно быть не менее 2 номеров.
- Каждое число должно быть уникальным (это не то, чего я пытаюсь добиться с помощью регулярного выражения).
- 0 недействителен, но 10, 100 и т.д.
Поскольку у меня нет опыта работы с регулярными выражениями, сейчас я использую два;
@"^(?:\[(?:[1-9]+[\d]*,)+(?:[1-9]+[\d]*){1}\])+$";
и
@"\[(?:[1-9]+[\d]*,)+(?:[1-9]+[\d]*){1}\]";
Я использую первый для проверки ввода, а второй — для получения всех совпадений с набором чисел в квадратных скобках.
Затем я использую манипуляции со строками .Net, чтобы обрезать квадратные скобки и извлечь числа, разобрать их и вычесть 1, чтобы получить нужный мне результат.
Мне было интересно, смогу ли я улучшить цифры, используя захваты, но не уверен, как они работают.
Окончательное решение:
В конце концов я использовал следующее регулярное выражение для проверки входной строки
@"^(?<set>\[(?:[1-9]\d{0,7}(?:]|,(?=\d))){2,})+$"
Шаблон agent-j подходит для сбора необходимой информации, но также соответствует строке типа «[1,2,3,4][5]» и потребует от меня дополнительной фильтрации результатов.
Я получаю доступ к захватам через именованную группу «набор» и использую второе простое регулярное выражение для извлечения чисел.
'[1-9]\d{0,7}' упрощает синтаксический анализ целых чисел, ограничивая числа до 99 999 999 и избегая исключений переполнения.
MatchCollection matches = new Regex(@"^(?<set>\[(?:[1-9]\d{0,7}(?:]|,(?=\d))){2,})+$").Matches(inputText);
if (matches.Count != 1)return;
CaptureCollection captures = matches[0].Groups["set"].Captures;
var resultJArray = new int[captures.Count][];
var numbersRegex = new Regex(@"\d+");
for (int captureIndex = 0; captureIndex < captures.Count; captureIndex++)
{
string capture = captures[captureIndex].Value;
MatchCollection numberMatches = numbersRegex.Matches(capture);
resultJArray [captureIndex] = new int[numberMatches.Count];
for (int numberMatchIndex = 0; numberMatchIndex < numberMatches.Count; numberMatchIndex++)
{
string number = numberMatches[numberMatchIndex].Value;
int numberAdjustedToZeroBase = Int32.Parse(number) - 1;
resultJArray [captureIndex][numberMatchIndex] = numberAdjustedToZeroBase;
}
}