#c# #regex
#c# #регулярное выражение
Вопрос:
Мне нужно проанализировать текстовый файл, подобный json, чтобы извлечь подобные объекты с помощью C # Regex:
foo {
line1
line2
}
bar {
line3
line4
}
т.е. объекты, которые начинаются и заканчиваются в начале строки.
Тестовый код C #:
Regex regex = new Regex("\n[^ \n] \{[.\n] \n\}");
string s = "nfoo {n line1n line2n}";
string v = regex.Match(s).Value;
это означает:
новая строка-> все, кроме пробела и новой строки-> «{» -> любая вещь плюс новая строка-> новая строка->}
Ожидаемый результат — просто s. Но результатом является пустая строка. Если я удалю "\n\}"
в конце:
Regex regex = new Regex("\n[^ \n] \{[.\n] ");
string s = "nfoo {n line1n line2n}";
string v = regex.Match(s).Value;
затем v="nfoo {n"
это работает, как и ожидалось, поэтому кажется, что проблема возникает "\n\}"
.
Комментарии:
1. «Нужно готовое решение» — значит, не та платформа, значит, это не сервис по написанию кода…
2. @ sticky bit вы понимаете, что я имею в виду, ответ — всего одна строка кода вместо программы. Поэтому будет лучше, если больше людей сосредоточится на ответе на вопрос, а не на использовании закона вне контекста.
3. синтаксический анализ и регулярное выражение — это совершенно разные вещи. Используйте / напишите синтаксический анализатор для синтаксического анализа
4. @ sticky bit и сэр Руфо: это именно то, что я подразумеваю под «готовым решением». Нестандартное решение не решит проблему, но может привести к обсуждению, которое отнимет время. Причина здесь в том, что написание синтаксического анализатора, например, на основе ANTLR, может стоить новичку нескольких дней, здесь для решения проблемы требуется только одна строка кода.
5.Возможно,
^S s*{n(?:(?!}).*n)*}
демонстрация
Ответ №1:
Для вашего примера данных вы могли бы сопоставить первую строку, заканчивающуюся открывающей фигурной скобкой.
Затем используйте повторяющийся шаблон , чтобы соответствовать всей строке , только если она не начинается с закрытия }
. Вы могли бы сделать это , используя негативный взгляд (?!})
.
Затем сопоставьте закрывающую фигурную скобку.
[rn]S s*{[rn](?:(?!}).*[rn])*}
О шаблоне
[rn]
Сопоставление новой строкиS s*
Сопоставьте 1 раз символ без пробелов, затем 0 раз символ без пробелов{[rn]
Открытие матча{
с последующим переводом строки(?:(?!})
Отрицательный прогноз, утверждение, что то, что находится прямо справа, не является}
.*[rn]
Сопоставьте любой символ, кроме новой строки, 0 раз, затем сопоставьте новую строку}
Закрытие соответствия}
Демонстрация регулярных выражений .NET | Демонстрация C #
Например:
Regex regex = new Regex(@"^S s*{[rn](?:(?!}).*[rn])*}");
string s = @"foo {
line1
line2
}
bar {
line3
line4
}";
Console.WriteLine(regex.Match(s).Value);
Результат:
foo {
line1
line2
}
Комментарии:
1. Можете ли вы предоставить рабочий пример на основе моего приведенного выше кода C #? Я пробую новое регулярное выражение (@»^ S s *{ n(?:(?!}).* n)*}»), но все равно получаем пустую строку.
2. @jw_ Я обновил свой ответ и добавил пример использования
[rn]
для сопоставления с новой строкой ideone.com/6TKDBo3. Пожалуйста, попробуйте это в моей приведенной выше строке: string s = » nfoo {n line1 n line2 n}»; Я все еще получаю пустую строку. Это из-за » r»? Мой текстовый файл содержит только » n», а не » r n».
4. Ах, если оно должно начинаться с новой строки, затем измените значение
^
на ` n`, например ideone.com/awTfJF Я обновил ответ.
Ответ №2:
Я нахожу рабочее решение:
Regex r1 = new Regex("\n[^ \n] \{[\s\S] ?\n\}");
string s = "nfoo {n line1n line2n}";
string v = r1.Match(s).Value;
теперь v=»nfoo {n line1n line2 n}»
Я новичок в регулярных выражениях, и после дополнительных исследований в ссылке говорится, что когда вы ставите «.» в «[]», точка больше не будет представлять «что-либо». Вы можете использовать «[s S]» для представления всего, включая новую строку.
Комментарии:
1. В этом случае, если у вас есть несколько элементов, вы можете сделать
[sS] ?
не жадным, используя a?
, иначе вы бы сопоставили больше, чем хотите, см. Демонстрацию2. @Четвертая птица, вы правы, действительно, я не тестировал приведенный выше код (на foo bar), я нашел это во время другого случая.