Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помощь по составлению регулярного выражения, Как лучше реализовать 
V
    Опции темы
Noobs
Дата 15.1.2009, 20:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 13.12.2008

Репутация: нет
Всего: нет



Всем привет, возникла сложность в составлении регулярного выражения, собственно сам текст, 3 строки:
Цитата

Y=v=1&n=751kbrdth6blk&l=i0d3j94dai/o&p=f1e0efe013000000&r=e6&lg
PH=fn=ymnKV1LUV8Acja2OdIRC&l=jshf_s
ws_v_2_243232_[slot_id]=hdgemcnsarefds

Требуется получить в одну переменную всё то что до знака =, в данном случае это Y и PH ну и соответственно ws_v_2_243232_[slot_id] , а в другую переменную всё что после этого знака. Сложность в том что в начале текста в фрагменте который нужно определить в первую переменную могут быть почти все символы и спец символы, а во второй переменной такие же знаки =, я пробовал делать так:
Код

(?<name>.*)=(?<value>.*)

Но он срабатывает правильно только тогда когда в фрагменте который нужно поместить во вторую переменную нет знака =, т.е в тексте который представлен выше найдется верно только
Цитата

ws_v_2_243232_[slot_id]=hdgemcnsarefds

так вот, как можно красиво составить регулярное выражения для данного случая? а так же есть ли в регулярных выражениях условия? что то вроде (?<name>.* NOT =). Конечно грубовато, но для примера пойдёт smile любые символы КРОМЕ =. Спасибо за помощь!

PM MAIL   Вверх
PashaPash
Дата 15.1.2009, 20:51 (ссылка)    | (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1233
Регистрация: 3.1.2008

Репутация: 13
Всего: 49



Noobs, от начала строки, как можно меньше любых символов, =, и все до конца строки. юзать с опцией multiline.
Код

^(?<name>.*?)=(?<value>.*)$

ЗЫ. регулярные выражения - зло.

Это сообщение отредактировал(а) PashaPash - 15.1.2009, 20:53


--------------------
PM MAIL WWW   Вверх
chaos
Дата 15.1.2009, 23:08 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Серийный программист
****


Профиль
Группа: Завсегдатай
Сообщений: 2979
Регистрация: 7.7.2004
Где: Екатеринбург

Репутация: нет
Всего: 44



Noobs, не знаю правил составления регекспов на С#, но на перле выглядело бы так
Код

^([^=]+)=(.+)$



PashaPash, то-то это зло засунули в Java, C#, Python, PHP, Perl(про него и говорить нечего, это его сила), .......


Регулярные выражения - сила, просто ее надо с умом применять!

Это сообщение отредактировал(а) chaos - 15.1.2009, 23:10
PM WWW   Вверх
Noobs
Дата 16.1.2009, 03:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 13.12.2008

Репутация: нет
Всего: нет



Всё получилось smile спасибо

Это сообщение отредактировал(а) Noobs - 16.1.2009, 03:21
PM MAIL   Вверх
PashaPash
Дата 17.1.2009, 13:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1233
Регистрация: 3.1.2008

Репутация: 13
Всего: 49



Цитата(chaos @  15.1.2009,  23:08 Найти цитируемый пост)

PashaPash, то-то это зло засунули в Java, C#, Python, PHP, Perl(про него и говорить нечего, это его сила), .......

Раз уж меня минусуют эа это утверждение - могу пояснить. 
1. Они реализованы везде по разному, совпадают только базовые конструкции. 
2. Хоть сколько-нибудь сложный regexp - совершенно не поддерживаемая вещь. Аналогичный код на C# - поиск первого =, отрезание строчки до и после - намного читабельнее регеэкспа. И работает быстрее. И шанс, что через пол года нуб, накнувшись на код, сходу поймет что происходит - намного выше. Я не призываю email валидировать вручную. Но решать задачу топикастера регекспами - это просто показать "и я знаю регулярные выражения". И обчеспечить в будущем нубу потерю рабочего дня, на хотя бы основ регекспов, т.е. написал регесп там, где не надо было == ограбил контору на 40-50$.
3. Даже простые задачи на регэкспах можно написать совершенно по разному. Вот chaos зачем-то понтанулся и впихнул [^=]. А я понтанулся, и впихнул нежадную выборку. У него почему-то +, хотя у топикастера - *. Это уже потенциально 2 бага - при пустом ключе и значении, и всего-то в 10 символах.
З.Ы. вот и помогай после этого людям smile


--------------------
PM MAIL WWW   Вверх
Bishop
Дата 17.1.2009, 16:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 3.6.2005
Где: Минск, Беларусь

Репутация: 6
Всего: 16



PashaPash, раз уж я минусую, прокомментирую.
"регулярные выражения - зло" — это была неконструктивная, неаргументированная, не относящаяеся к теме, провоцирующая флейм и "разжигающая" холивор, реплика. Что и имеем smile
1. Сложно спорить. Различия настолько единичны и редки, что заострять на них внимание несерьёзно.
3. [^=]= и .*?= совсем разные вещи, и первая в теории производительнее в разы (на практике, благодаря оптимизации они будут работать одинаково). + и * — регулярные выражения позволяют совместить проверку валидности строки с её разбором, причем максимально лаконично.
2. Ваши представления о читаемости тоже, по меньшей мере странные. Предлагается сравнить:
Код
private void button1_Click(object sender, EventArgs e)
{
    string str = @"Y=v=1&n=751kbrdth6blk&l=i0d3j94dai/o&p=f1e0efe013000000&r=e6&lg
PH=fn=ymnKV1LUV8Acja2OdIRC&l=jshf_s
ws_v_2_243232_[slot_id]=hdgemcnsarefds";

    _log("split");
    foreach (string s in str.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
    {
        string[] vals = s.Split("=".ToCharArray(), 2);
        if (vals.Length != 2)
            _log("bad line");
        else 
           _log(vals[0], vals[1]);
    }

    _log("plain");
    int index;
    string strc = str;
    do
    {
        index = strc.IndexOfAny("\r\n".ToCharArray());
        string line = "";
        if (index < 0)
            line = strc;
        else
        {
            line = strc.Substring(0, index);
            strc = strc.Substring(index + 1);
        }
        if (line.Length == 0) { _log("skip"); continue; }
        int index2 = line.IndexOf("=");
        if (index2 < 0)
            _log("bad line");
        else
        {
            string name = line.Substring(0, index2);
            string value = line.Substring(index2 + 1);
            _log(name, value);
        }
    }
    while (index >= 0);

    _log("regex");
    foreach (string s in Regex.Split(str, @"[\r\n]+"))
    {
        Match m = Regex.Match(s, "^(?<name>[^=]+)=(?<value>.*)$");
        if (m.Success)
            _log(m.Groups["name"].Value, m.Groups["value"].Value);
        else
            _log("bad line");
    }
}
private void _log(string a)
{
    _log(a, "");
}
private void _log(string a, string b)
{
    if (b == "")
        listBox1.Items.Add(a);
    else
        listBox1.Items.Add(string.Format("name: {0}; value: {1}", a, b));
}

Первый и третий вариант были написаны с ходу, второй отнял минут десять. Неужели второй легче прочитать? Отказываюсь понимать.
Цитата
И обчеспечить в будущем нубу потерю рабочего дня, на хотя бы основ регекспов

Предлагаете оберегать новичков от любых сложностей? За рабочий день можно изучить регекспы в совершенстве. А нанимая молодого неопытного сотрудника, работодатель обычно понимает, что придётся тратить время и средства на его обучение. Предлагаете писать такой код, чтобы в любой момент работодатель мог заменить весь штат профессионалов на студентов второго курса? Тоже вариант. Опять же сложно спорить. Но это не единственно-верный путь и не надо его так пропагандировать.

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

PM WWW ICQ   Вверх
PashaPash
Дата 17.1.2009, 16:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1233
Регистрация: 3.1.2008

Репутация: 13
Всего: 49



Цитата(Bishop @  17.1.2009,  16:14 Найти цитируемый пост)
"регулярные выражения - зло" — это была неконструктивная, неаргументированная, не относящаяеся к теме, провоцирующая флейм и "разжигающая" холивор, реплика. Что и имеем 

Пока холиваришь только ты.
Цитата(Bishop @  17.1.2009,  16:14 Найти цитируемый пост)
Сложно спорить. Различия настолько единичны и редки, что заострять на них внимание несерьёзно.

А я и не заостряю. Я просто очень непрозрачно намкнул что надо сначала научится использовать регулярные выражения, а потом уже "внедрять".
Цитата(Bishop @  17.1.2009,  16:14 Найти цитируемый пост)

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

Почему именно второй? Я имел в виду что-то вроде первый vs третий, ну или 
Код

            TextReader reader = new StringReader(str);
            string line;
            while ((line = reader.ReadLine()) != null)
            {
                string[] vals = line.Split("=".ToCharArray(), 2);
                _log(vals[0], vals[1]);
            }

на случай если входной текст большой, и или читаетсяиз потока. По читабельности лучше регулярных выражений, IMHO. Можно даже Split убрать, оставить IndexOf. И работает быстрее, и память не кушает, если читать из файла....
Цитата(Bishop @  17.1.2009,  16:14 Найти цитируемый пост)
Предлагаете оберегать новичков от любых сложностей? За рабочий день можно изучить регекспы в совершенстве. А нанимая молодого неопытного сотрудника, работодатель обычно понимает, что придётся тратить время и средства на его обучение. Предлагаете писать такой код, чтобы в любой момент работодатель мог заменить весь штат профессионалов на студентов второго курса? Тоже вариант. Опять же сложно спорить. Но это не единственно-верный путь и не надо его так пропагандировать.

Все крупные фирмы садят новичков-студентов прежде всего на поддержку старых проектов, никто не дает с нуля писать. И никто не говорит им - можете 3 месяца ничего не делать, учится, а мы будем вам платить зарплату. И да, код надо писать так, чтобы студент 3-го курса смог его прочитать и исправить, не тупля по дню над 4 строчками.
Цитата
Некоторым программистам, когда они сталкиваются с какой-то проблемой, приходит в голову такая мысль
— О, я знаю! Это можно сделать с помощью регулярных выражений!
Это означает, что у этого програмиста теперь ДВЕ проблемы.
 (с) Баш.

Добавлено через 11 минут и 53 секунды
ЗЫ - и зачем у тебя в 3-м варианте split? Почему не Matches(..., RegexOptions.Multiline)? Намного читабельнее получилось бы. ;)

Это сообщение отредактировал(а) PashaPash - 17.1.2009, 16:42


--------------------
PM MAIL WWW   Вверх
Bishop
Дата 17.1.2009, 18:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 3.6.2005
Где: Минск, Беларусь

Репутация: 6
Всего: 16



PashaPash, 
Конечно:
Код
_log("regex 2");
foreach (Match m in Regex.Matches(str, "^(?<name>[^=\n\r]+)=(?<value>[^\n\r]+)$", RegexOptions.Multiline))
    _log(m.Groups["name"].Value, m.Groups["value"].Value);

Но этот код не равнозначен, потому как опускает неподошедшие строки.

Ваш же код выдаст ошибку, если в строке нет "=". С IndexOf нужно проверять неотрицательность результата. А как быть если "=" первая или последняя в строке. В случае регекспов это решается простой правкой шаблона, в остальных — рядом дополнительных проверок.
PM WWW ICQ   Вверх
PashaPash
Дата 17.1.2009, 22:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1233
Регистрация: 3.1.2008

Репутация: 13
Всего: 49



Цитата(Bishop @  17.1.2009,  18:22 Найти цитируемый пост)
Но этот код не равнозначен, потому как опускает неподошедшие строки.

Ваш же код выдаст ошибку, если в строке нет "=". С IndexOf нужно проверять неотрицательность результата. А как быть если "=" первая или последняя в строке. В случае регекспов это решается простой правкой шаблона, в остальных — рядом дополнительных проверок. 

А никто не знает на что именно надо проверять, и надо ли проверять вообще. Опускать неподошедшие строки, или выдавать подробные ошибки. В случае не-регеспов гораздо проще узнать что именно неверно в строке. В случае регеспов - !m.Success - и все, гадай что там неправильно.
Вообще достаточно посмотреть на этот топик - если регеспы тах хороши, то почему топикастеру понадобилось аж 7 часов чтобы решить мегазадачу? При том, что в начале этих 7 часов он уже знал про регэспы, и даже про grouping constructs.


--------------------
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0500 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.