|
@@ -1,144 +1,109 @@
|
|
-# Конспект лекции "Форматы файлов"
|
|
|
|
-## CSV
|
|
|
|
|
|
+# Конспект лекции "Регулярные выражения"
|
|
|
|
+## Регулярки в C#
|
|
```
|
|
```
|
|
-using System.Globalization;
|
|
|
|
-using CsvHelper;
|
|
|
|
-using CsvHelper.Configuration;
|
|
|
|
-
|
|
|
|
-using (var reader = new StreamReader("./people.dat")) {
|
|
|
|
- using (var csv = new CsvReader(
|
|
|
|
- reader, CultureInfo.InvariantCulture))
|
|
|
|
- {
|
|
|
|
- var records = csv.GetRecords<Foo>();
|
|
|
|
- foreach (var record in records) {
|
|
|
|
- Console.WriteLine("{0}, {1}", record.description, record.value);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+string s = "Бык тупогуб, тупогубенький бычок, у быка губа бела была тупа";
|
|
|
|
+Regex regex = new Regex(@"туп(\w*)");
|
|
|
|
+MatchCollection matches = regex.Matches(s);
|
|
|
|
+if (matches.Count > 0)
|
|
|
|
+{
|
|
|
|
+ foreach (Match match in matches)
|
|
|
|
+ Console.WriteLine(match.Value);
|
|
}
|
|
}
|
|
-
|
|
|
|
-public class Foo
|
|
|
|
|
|
+else
|
|
{
|
|
{
|
|
- public string description { get; set; }
|
|
|
|
- public double value { get; set; }
|
|
|
|
|
|
+ Console.WriteLine("Совпадений не найдено");
|
|
}
|
|
}
|
|
```
|
|
```
|
|
```
|
|
```
|
|
-строка с пробелами, 123,15
|
|
|
|
-строка
|
|
|
|
-с переносом
|
|
|
|
-строки, 456
|
|
|
|
|
|
+тупогуб
|
|
|
|
+тупогубенький
|
|
|
|
+тупа
|
|
```
|
|
```
|
|
-### Запись в CSV
|
|
|
|
|
|
+## Поиск с группами
|
|
```
|
|
```
|
|
-// использую не стандартный формат
|
|
|
|
-var config = new CsvConfiguration(
|
|
|
|
- CultureInfo.InvariantCulture) {
|
|
|
|
- Delimiter = ";",
|
|
|
|
- HasHeaderRecord = false };
|
|
|
|
|
|
+string text = "One car red car blue car";
|
|
|
|
+string pat = @"(\w+)\s+(car)";
|
|
|
|
|
|
-// создаю тестовые данные
|
|
|
|
-var records = new List<Foo>
|
|
|
|
-{
|
|
|
|
- new Foo {
|
|
|
|
- description ="тест записи\nмногострочного текста",
|
|
|
|
- value = 12.34 },
|
|
|
|
- new Foo {
|
|
|
|
- description = "просто, текст, с запятыми",
|
|
|
|
- value = 0 }
|
|
|
|
-};
|
|
|
|
|
|
+Regex r = new Regex(pat, RegexOptions.IgnoreCase);
|
|
|
|
|
|
-using (var writer = new StreamWriter("./test3.csv"))
|
|
|
|
-using (var csv = new CsvWriter(writer, config))
|
|
|
|
|
|
+Match m = r.Match(text);
|
|
|
|
+int matchCount = 0;
|
|
|
|
+// можно искать не одно вхождение, а несколько
|
|
|
|
+while (m.Success)
|
|
{
|
|
{
|
|
- csv.WriteRecords(records);
|
|
|
|
|
|
+ Console.WriteLine("Match"+ (++matchCount));
|
|
|
|
+ // тут можно было бы перебирать по длине массива Groups,
|
|
|
|
+ // но мы по своему шаблону и так знаем, что у нас две подгруппы
|
|
|
|
+ for (int i = 1; i <= 2; i++)
|
|
|
|
+ {
|
|
|
|
+ Console.WriteLine($"Group {i}='{m.Groups[i]}'");
|
|
|
|
+ }
|
|
|
|
+ // поиск следующей подстроки соответсвующей шаблону
|
|
|
|
+ m = m.NextMatch();
|
|
}
|
|
}
|
|
```
|
|
```
|
|
```
|
|
```
|
|
-"тест записи
|
|
|
|
-многострочного текста";12.34
|
|
|
|
-просто, текст, с запятыми;0
|
|
|
|
|
|
+Match1
|
|
|
|
+Group 1='One'
|
|
|
|
+Group 2='car'
|
|
|
|
+Match2
|
|
|
|
+Group 1='red'
|
|
|
|
+Group 2='car'
|
|
|
|
+Match3
|
|
|
|
+Group 1='blue'
|
|
|
|
+Group 2='car'
|
|
```
|
|
```
|
|
-## JSON
|
|
|
|
-### Пример сериализации
|
|
|
|
|
|
+## Параметр RegexOptions
|
|
|
|
+### 示例1
|
|
```
|
|
```
|
|
-var person = new Person
|
|
|
|
-{
|
|
|
|
- name = "Имя",
|
|
|
|
- age = 18,
|
|
|
|
- date = "2024-03-07"
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-string json = JsonConvert.SerializeObject(
|
|
|
|
- person, Formatting.Indented);
|
|
|
|
-
|
|
|
|
-Console.WriteLine(json);
|
|
|
|
|
|
+string s = "Бык тупогуб, тупогубенький бычок, у быка губа бела была тупа";
|
|
|
|
+Regex regex = new Regex(@"\w*губ\w*");
|
|
```
|
|
```
|
|
```
|
|
```
|
|
-{
|
|
|
|
- "name": "Имя",
|
|
|
|
- "age":18,
|
|
|
|
- "date":"2024-03-07"
|
|
|
|
-}
|
|
|
|
|
|
+Process finished with exit code 0.
|
|
```
|
|
```
|
|
-### Сериализация (Преобразование объекта в JSON-строку)
|
|
|
|
|
|
+### 例子2
|
|
```
|
|
```
|
|
-var PersonList = new List<Person>() {
|
|
|
|
- new Person {name="Иванов", age=25, date=new DateTime(2021,1,1)},
|
|
|
|
- new Person {name="Петров", age=35, date=new DateTime(2021,1,2)}
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-// создаем объект сериализатора, указав, что на входе
|
|
|
|
-// будет МАССИВ объектов Person
|
|
|
|
-var Serializer = new DataContractJsonSerializer(typeof(Person[]));
|
|
|
|
-
|
|
|
|
-using (var streamWriter = new StreamWriter("test1.json"))
|
|
|
|
-{
|
|
|
|
- Serializer.WriteObject(
|
|
|
|
- streamWriter.BaseStream,
|
|
|
|
- // Преобразуем список (List) объектов в МАССИВ
|
|
|
|
- PersonList.ToArray()
|
|
|
|
- );
|
|
|
|
-}
|
|
|
|
|
|
+string s = "456-435-2318";
|
|
|
|
+Regex regex = new Regex(
|
|
|
|
+ @"\d{3}-\d{3}-\d{4}");
|
|
```
|
|
```
|
|
```
|
|
```
|
|
-[{"age":25,"date":"\/Date(1609448400000+0300)\/","name":"Иванов"},{"age":35,"date":"\/Date(1609534800000+0300)\/","name":"Петров"}]
|
|
|
|
|
|
+Process finished with exit code 0.
|
|
```
|
|
```
|
|
-### Десериализация
|
|
|
|
|
|
+## Проверка на соответствие строки формату
|
|
```
|
|
```
|
|
-[DataContract]
|
|
|
|
-internal class Person
|
|
|
|
|
|
+string pattern = @"^(?("")(""[^""]+?""@)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])@))" +
|
|
|
|
+ @"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9]{2,17}))$";
|
|
|
|
+while (true)
|
|
{
|
|
{
|
|
- // создаем приватную переменную для хранения даты
|
|
|
|
- private DateTime privateDate;
|
|
|
|
-
|
|
|
|
- [DataMember]
|
|
|
|
- public string name { get; set; }
|
|
|
|
-
|
|
|
|
- [DataMember]
|
|
|
|
- public string age { get; set; }
|
|
|
|
-
|
|
|
|
- // создаем ПРИВАТНОЕ СТРОКОВОЕ свойство и с помощью атрибутов меняем ему имя для сериализатора
|
|
|
|
- [DataMember(Name = "date")]
|
|
|
|
- private string StringDate {
|
|
|
|
- get {
|
|
|
|
- return privateDate.ToString("yyyy-MM-dd");
|
|
|
|
- }
|
|
|
|
- set {
|
|
|
|
- // 2021-03-21
|
|
|
|
- // 0123456789
|
|
|
|
- privateDate = new DateTime(
|
|
|
|
- Convert.ToInt32(value.Substring(0, 4)),
|
|
|
|
- Convert.ToInt32(value.Substring(5, 2)),
|
|
|
|
- Convert.ToInt32(value.Substring(8, 2))
|
|
|
|
- );
|
|
|
|
- }
|
|
|
|
|
|
+ Console.WriteLine("Введите адрес электронной почты");
|
|
|
|
+ string email = Console.ReadLine();
|
|
|
|
+
|
|
|
|
+ if (Regex.IsMatch(email, pattern, RegexOptions.IgnoreCase))
|
|
|
|
+ {
|
|
|
|
+ Console.WriteLine("Email подтвержден");
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
-
|
|
|
|
- // публичное свойство "дата" скрываем от сериализатора
|
|
|
|
- [IgnoreDataMember]
|
|
|
|
- public DateTime date {
|
|
|
|
- get { return privateDate; }
|
|
|
|
- set { privateDate = value; }
|
|
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ Console.WriteLine("Некорректный email");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
```
|
|
|
|
+```
|
|
|
|
+Введите адрес электронной почты
|
|
|
|
+dkljfsljkf@gmail.com
|
|
|
|
+Email подтвержден
|
|
|
|
+```
|
|
|
|
+## Замена и метод Replace
|
|
|
|
+```
|
|
|
|
+string s = "Мама мыла раму. ";
|
|
|
|
+string pattern = @"\s+";
|
|
|
|
+string target = " ";
|
|
|
|
+Regex regex = new Regex(pattern);
|
|
|
|
+string result = regex.Replace(s, target);
|
|
|
|
+```
|
|
|
|
+```
|
|
|
|
+Process finished with exit code 0.
|
|
|
|
+```
|