Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.65/40: Рейтинг темы: голосов - 40, средняя оценка - 4.65
1 / 1 / 0
Регистрация: 18.08.2015
Сообщений: 48
1

Регулярные выражения, исключить строки содержащие слова

11.04.2018, 07:58. Просмотров 8138. Ответов 6

Добрый день,
Помогите пожалуйста решить проблему с исключением строк в которых встречаются определенные подстроки.

Задача в общем виде примерно такая:
Имеем несколько категорий:
  • Негазированная вода
  • Газированная вода
  • Сладкая вода
  • Чай
И набор строк, который вводит пользователь (конечно же как попало):
  • вода
  • негазированная вода
  • минеральная вода
  • водичка
  • вода газированная
  • газ. вода
  • вода с газом
  • Сладкая вода
  • Сладкая газированная вода
  • Газированная вода (сладкая)
  • Вода сладкая газированная
  • Сладкий чай
  • Зеленый чай
Мне нужно для каждой строки категории написать регулярное выражение таким образом,
чтобы каждая строка из набора идентифицировалась только к одной категории
Т.е. /.*вод.*/gi не подойдет.

Важно:
  1. ключевые слова могут быть поменяны местами: "вода газированная" и "газ. вода"
  2. при попадании в одну категорию в другую попасть не должно
Как я понял для такой задачи подойдет Просмотр с отрицанием (?!шаблон),
но он блин все равно включает в выборку не нужные строки...

Пробовал такие запросы
для негазированной воды:
.*(?!слад|\bгаз|^газ).*(вод).*
для нескольких необходимых слов использовал ссылки на результат:
.*(?!слад).*(вод|\bгаз|^газ).*(?!слад|\1).*(вод|\bгаз|^газ). *

Ниче не работает, подскажите как правильно написать, я с регулярками раньше не работал...

Тестил на regex101.com , не понял еще почему на этом сайте вообще ничего не выдает с "\bгаз"
это же как бы граница слова (чтобы "негазированный" не подхватил)
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
11.04.2018, 07:58
Ответы с готовыми решениями:

Регулярные выражения для слова в алфавите {a,b,c}, содержащие подслово вида bxa
Помогите пожалуйста: Написать регулярное выражение а)для слова в алфавите {a,b,c}, содержащие...

Регулярные выражения. Найти строки содержащие значения переменной s в качестве подстроки
Здравствуйте! я новичок в с#. Как сделать такое задание? Дан текстовый файл f и строка s,...

Удалить из строки все слова начинающиеся с гласных, используя регулярные выражения
В задании нужно удалить из строки все слова начинающиеся с гласных(русских) используя при этом...

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

6
2224 / 1728 / 864
Регистрация: 21.12.2010
Сообщений: 3,073
Записей в блоге: 11
11.04.2018, 10:55 2
Цитата Сообщение от novikoff92 Посмотреть сообщение
вообще ничего не выдает с "\bгаз"
граница слова \b работает с латинскими буквами

Добавлено через 2 часа 11 минут
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
using System.Text.RegularExpressions;
using System;
using System.Collections.Generic;
using System.Collections;
 
namespace nms
{
    class Program
    {
        static void Main()
        {
            ArrayList al = new ArrayList
            {
                "вода",
                "негазированная вода",
                "минеральная вода",
                "водичка",
                "вода газированная",
                "газ. вода",
                "вода с газом",
                "Сладкая вода",
                "Сладкая и газированная вода",
                "Газированная вода (сладкая)",
                "Вода сладкая газированная",
                "Сладкий чай",
                "Чай зеленый"
            };
 
            Dictionary<string, string> dct = new Dictionary<string, string>
            {
                { "^(?!.*?(?:[Чч]ай|[Сс]ладкая).*?)(?:^|.*?[^е])[Гг]аз(?!.*?(?:[Чч]ай|[Сс]ладкая))", "Газированная вода" },
                { "[Сс]ладкая", "Сладкая вода" },
                { "[Чч]ай", "Чай" },
                { "^(?!.*?([Чч]ай|[Сс]ладкая|(?:^|[^е])[Гг]аз))", "Негазированная вода" }
            };
 
            int totalFound = 0;
            foreach(string str in al)
            {
                bool found = false;
                foreach(KeyValuePair<string, string> pr in dct)
                {
                    if (Regex.Match(str, pr.Key).Success)
                    {
                        Console.WriteLine(String.Format("{0,-30}", str) + "  =>  " + pr.Value);
                        found = true;
                        ++totalFound;
                        // break; // проверяем каждую регулярку на каждой фразе
                    }
                }
                if(!found)
                {
                    Console.WriteLine(String.Format("{0,-30}", str) + "  =>  Not Found");
                }
            }
            if(totalFound != al.Count)
            {
                Console.WriteLine("\nERROR: totalFound = " + totalFound.ToString() + ", al.Count = " + al.Count.ToString());
            }
        }
    }
}
1
983 / 617 / 362
Регистрация: 07.11.2015
Сообщений: 984
11.04.2018, 10:55 3
Можно сделать набор относительно простых регулярок, но подобрать порядок их проверки и при первом совпадении останавливать поиск.
C#
1
2
3
4
5
6
7
Dictionary<string, string> patterns = new Dictionary<string, string>()
{
    {"Чай",                 @"(?i)\bЧай\b"},
    {"Сладкая вода",        @"(?i)(?=.*\bсладк)(?=.*\bвод)"},
    {"Газированная вода",   @"(?i)(?=.*\bгаз)(?=.*\bвод)"},
    {"Негазированная вода", @"(?i)(?=.*\bвод)"}
};
http://rextester.com/ERMSZB44867
0
2224 / 1728 / 864
Регистрация: 21.12.2010
Сообщений: 3,073
Записей в блоге: 11
11.04.2018, 11:01 4
Emilien, я решил сделать чтоб находил независимо от порядка проверки
0
1 / 1 / 0
Регистрация: 18.08.2015
Сообщений: 48
11.04.2018, 15:20  [ТС] 5
igorrr37, код работает,

только тут все что он не смог найти, считает "Негазированной водой",
И в реальном примере больше перекрестных вариантов, например:
  • Сладкий чай
  • Сладкая вода
  • вода + чай
это может относится к разным категориям
т.е. надо указывать как шаблоны слов которые не должны быть в строке, так и какие должны (причем все слова)
например
в "Газированная вода" должны быть "газ и "вод" (обязательно оба) и не должно быть "чай", "негаз" и еще че нибудь

Что то типа, но не работает:
C#
1
 { "^(?!.*?(?:чай|слад).*?)((?:^|.*?[^е])газ|вод)(?!.*?(?:чай|слад|\\1).*?)((?:^|.*?[^е])газ|вод)(?!.*?(?:чай|слад))", "Газированная вода" },
Вопросы по рег. выражениям:
как мне сослаться на группу ((?:^|.*?[^е])газ|вод), чтобы не писать постоянно
и чем отличается .*? от .*







Добавлено через 2 часа 6 минут

Урааа! нашел решение!

В общем, в моем случае подходит строка такого вида:
^(?!.*слад|.*чай|.*негаз)(?=.*вод)(?=.*газ).*$
Где
слад, чай, негаз - маски слов которых точно не должно быть в строке
вод, газ - маски слов которые обязательно должны быть в строке

Т.е.
C#
1
2
3
4
5
6
7
Dictionary<string, string> dct = new Dictionary<string, string>
{
    { "^(?!.*слад|.*чай|.*негаз)(?=.*вод)(?=.*газ).*$" , "Газированная вода" },
    { "^(?!.*чай)(?=.*вод)(?=.*слад).*$"               , "Сладкая вода" },
    { "^(?=.*чай).*$"                                  , "Чай" },
    { "^(?!.*слад|.*чай|.*(?:^|[^е])газ)(?=.*вод).*$"  , "Негазированная вода" }
};
И с включенной опцией игнора регистра вроде нормально отрабатывает:
C#
1
Regex.Match(str, pr.Key, RegexOptions.IgnoreCase)
Если где то я ошибаюсь, ткните пожалуйста, где именно...
А если это выражение все таки работает как надо, то вдруг кому пригодится
0
2224 / 1728 / 864
Регистрация: 21.12.2010
Сообщений: 3,073
Записей в блоге: 11
11.04.2018, 15:37 6
а если так "Негазированная вода и чай газированная"
0
1 / 1 / 0
Регистрация: 18.08.2015
Сообщений: 48
12.04.2018, 06:42  [ТС] 7
Цитата Сообщение от igorrr37 Посмотреть сообщение
а если так "Негазированная вода и чай газированная"
Так пишет что "чай", потому что у него не указано исключающих слов.
Но включает его только туда, и если исключения прописать, то он выдаст что не найден
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
12.04.2018, 06:42

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

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

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

Из матрицы исключить строки, содержащие хотя бы один нулевой элемент
из матрицы целых чисел разностью 4х5 исключить строки, содержащие хотябы один нулевой эдемент ...

ЧПУ. Замена строк, регулярные выражения. Как правильно использовать переменную в регулярные выражения ?
Здравствуйте! Решил реализовать ЧПУ на своем сайте. Первый этап это замена всех реальных ссылок на...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.