Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Правильное написание regexp
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt Общие вопросы
AD
Буду благодарен, если напишите правильный regexp для след. цели: надо найти в строке символы, не являющиеся цифрами и точкой/запятой.
Tonal
[^\d.,]
Litkevich Yuriy
Tonal, выглядит почти так
;)
AD
Хотел немного уточнить - а как сделать так, чтобы пробелы он тоже пропускал, есть ли значок "или" в регэкспе (нужно для того, чтобы пропускать спец. фразы - например, "C_OFF, C_ON, W_OFF, W_ON")?
AD
//
Вот сделал вот такой regexp!
QRegExp rx("[^\\d.,\bC_ON\b\bW_ON\b\bC_OFF\b\bW_OFF\b\b_ON\b\b_OFF\b\\s]")

Теперь осталось только додумать, чтобы отдельные символы "_", которые встречаются не в этих словосочетаниях тоже удалялись.
Помогите, пожалуйста, доработать эту штуку!
Litkevich Yuriy
Цитата(AD @ 28.8.2008, 20:41) *
символы "_",
так его и напиши
AD
В регэкспе как раз те словосочетания, которые не удаляются! Точнее удаляются все те, что не попадают под описание регэкспа. Но отдельные символы "_" он оставляет, а мне надо, чтобы они удалялись!!!!
Litkevich Yuriy
вот и впиши его туда
AD
Цитата(Litkevich Yuriy @ 28.8.2008, 18:02) *
вот и впиши его туда

Блин, если я его впишу - он тем более удаляться не будет, а мне надо чтобы отдельные "_" удалялись!!!!
Litkevich Yuriy
Так давай с начала,
надо найти в строке символы, не являющиеся:
цифрами
. (точкой)
, (запятой)
_ (подчеркиванием), кроме случаев: C_OFF, C_ON, W_OFF, W_ON

так?
AD
Цитата(Litkevich Yuriy @ 28.8.2008, 18:46) *
Так давай с начала,
надо найти в строке символы, не являющиеся:
цифрами
. (точкой)
, (запятой)
_ (подчеркиванием), кроме случаев: C_OFF, C_ON, W_OFF, W_ON

так?

Наоборот для последнего случая: не являющимися C_OFF, C_ON, W_OFF, W_ON.
Litkevich Yuriy
смысл помоему не поменялся.
Т.е. анализатор "_" не находит, а "C_OFF" находит
AD
Цитата(Litkevich Yuriy @ 28.8.2008, 19:06) *
смысл помоему не поменялся.
Т.е. анализатор "_" не находит, а "C_OFF" находит

бррр, так мне и не надо чтобы он находил "_". А он как раз-таки почему-то его находит!!!!! :)
Tonal
Цитата(AD @ 28.8.2008, 20:41) *
QRegExp rx("[^\\d.,\bC_ON\b\bW_ON\b\bC_OFF\b\bW_OFF\b\b_ON\b\b_OFF\b\\s]")

Ужос!
Ты бы прочитал что-нибудь по регэкспам, стало бы жить сильно проще.

Краткое описание:
Это описание может содержать неточности, для уточнения смотри ассистента!
Конструкция [что-то здесь] - это всегда 1 символ.
Она может включать явное перечисление символов, указание диапазона символов (например a-z означает любой символ начиная с a и оканчивая z), групповые символы (например \d - эквивалентно 0-9, а \s - любой из пробельных символов, \w - любой из символов слова).
Кроме того, если сразу после открывающей скобки стоил символ ^, конструкция инвертируется, и означает 1 любой символ кроме указанных.
Да, некоторые специальные символы внутри конструкции меняют своё значение. Например . обозначает именно точку а не все символы. \b символ забоя (вроде '\07')...

Теперь сам можешь разобрать что ты написал. :)

Про задачу. Давай ты вообще без регекспов, на человеческом языке напишешь чего тебе нужно?
Например: У меня есть строка содержащая такое (примеры).
Я хочу, сделать с ней что-то (например выбрать все числа, или числа и спец-значения, или убрать ненужные символы...)
И вместе подумаем как это проще и понятнее реализовать.
AD
Цитата
Ужос!
Ты бы прочитал что-нибудь по регэкспам, стало бы жить сильно проще.

Краткое описание:
Это описание может содержать неточности, для уточнения смотри ассистента!
Конструкция [что-то здесь] - это всегда 1 символ.
Она может включать явное перечисление символов, указание диапазона символов (например a-z означает любой символ начиная с a и оканчивая z), групповые символы (например \d - эквивалентно 0-9, а \s - любой из пробельных символов, \w - любой из символов слова).
Кроме того, если сразу после открывающей скобки стоил символ ^, конструкция инвертируется, и означает 1 любой символ кроме указанных.
Да, некоторые специальные символы внутри конструкции меняют своё значение. Например . обозначает именно точку а не все символы. \b символ забоя (вроде '\07')...

Теперь сам можешь разобрать что ты написал. :)

Про задачу. Давай ты вообще без регекспов, на человеческом языке напишешь чего тебе нужно?
Например: У меня есть строка содержащая такое (примеры).
Я хочу, сделать с ней что-то (например выбрать все числа, или числа и спец-значения, или убрать ненужные символы...)
И вместе подумаем как это проще и понятнее реализовать.


Мне необходимо удалять из строки все символы, которые не относятся к:
  • цифрам
  • точке
  • запятой
  • специализированным словосочетаниям: как пример, C_OFF, _OFF, _ON

Что значит символы забоя? Если честно, я просто не понимаю некоторых спец. терминов, можно пояснить, пожалуйста? Я по-диагонали читал ассистент. Там про \b написано:
Цитата
\b - A word boundary. For example the regexp \bOK\b means match immediately after a word boundary (e.g. start of string or whitespace) the letter 'O' then the letter 'K' immediately before another word boundary (e.g. end of string or whitespace). But note that the assertion does not actually match any whitespace so if we write (\bOK\b) and we have a match it will only contain 'OK' even if the string is "It's OK now".


Потому, я и решил, что можно использовать эти конструкции. Спасибо за ответ, содержащий разумную критику! :) Буду ждать помощи в правильно решении этой задачи!!! :)
Litkevich Yuriy
Цитата(AD @ 29.8.2008, 14:09) *
символы забоя?
онже backspase, переход на символ назад с затиранием символа

Цитата(AD @ 29.8.2008, 14:09) *
про \b написано:
это когда он не в квадратных скобках, см. тут (PDF)
Tonal
1) Про символ '\b' нужно читать не в ассистенте, а в учебнике по С/С++ там же где и про символ '\n'
2) Когда в С/С++ пишешь регулярку нужно помнить об отслешивении слешей. Т.е. если в документации написано, что конструкция \b это граница слова, а ты хочешь найти скажем слово word, то в коде это будет выглядеть так:
QRegExp rx("\\bword\\b")

3) Если ты ещё не понял, конструкция (слеши не отслешены):
[\bC_ON\b\bW_ON\b\bC_OFF\b\bW_OFF\b] эквивалентна [\bC_ONWF] и найдёт 1 из перечисленных символов, но не их последовательность.
4) Пусть у тебя есть строка:
"123.3 - 123 C_ON, W_ON, 1235, -456, C_OFF + W_OFF / Word G_is , OFF bat . War 5 dog_cat 67 ONtologi"
После удаления у тебя получится:
"123.3123C_ON,W_ON,1235,456,C_OFFW_OFF,.567"
Именно это тебе нужно?
AD
Цитата(Tonal @ 29.8.2008, 13:15) *
1) Про символ '\b' нужно читать не в ассистенте, а в учебнике по С/С++ там же где и про символ '\n'
2) Когда в С/С++ пишешь регулярку нужно помнить об отслешивении слешей. Т.е. если в документации написано, что конструкция \b это граница слова, а ты хочешь найти скажем слово word, то в коде это будет выглядеть так:
QRegExp rx("\\bword\\b")

3) Если ты ещё не понял, конструкция (слеши не отслешены):
[\bC_ON\b\bW_ON\b\bC_OFF\b\bW_OFF\b] эквивалентна [\bC_ONWF] и найдёт 1 из перечисленных символов, но не их последовательность.
4) Пусть у тебя есть строка:
"123.3 - 123 C_ON, W_ON, 1235, -456, C_OFF + W_OFF / Word G_is , OFF bat . War 5 dog_cat 67 ONtologi"
После удаления у тебя получится:
"123.3123C_ON,W_ON,1235,456,C_OFFW_OFF,.567"
Именно это тебе нужно?

Нет для приведенной строки получилось совсем не то, что мне надо! Согласен, что у меня корявая конструкция!!! Как сделать правильно?
Tonal
Напиши какие строки у тебя на входе, и что тебе нужно получить на выходе.
AD
Цитата
Напиши какие строки у тебя на входе, и что тебе нужно получить на выходе.

Входная строчка:
str = "7.3W_ON Unknown_event 4.1_ON 1C_OFF TTA_FAIL_TRUE RESET"
Выходная:
str = "7.3W_ON 4.1_ON 1C_OFF"

Например, вот так!
Tonal
1) Составляем выражение, которое найдёт последовательность символов которую нужно оставить:
[\d.]+[WC]?_O(N|FF)\b
Кстати, минус у чисел может быть?
И ещё куда-то нужно запятую присобачить - из примера не видно.
2) Создаём QRegExp с этим выражением.
3) Для исходной строки ищем все вхождения и собираем из них выходящую строку.

Вот реализация на python-е:
import re

def clear_str(str):
  regExp = re.compile(r'[\d.]+[WC]?_O(N|FF)\b')
  return ' '.join(regExp.findAll(str))

Думаю перевести на С++ труда не составит? :)

П.С. Приведённое выражение поймает и такую последовательность: 1.2.3.4.5._ON
Непонятно нужно ли с этим бороться...
AD
Цитата(Tonal @ 30.8.2008, 1:08) *
1) Составляем выражение, которое найдёт последовательность символов которую нужно оставить:
[\d.]+[WC]?_O(N|FF)\b
Кстати, минус у чисел может быть?
И ещё куда-то нужно запятую присобачить - из примера не видно.
2) Создаём QRegExp с этим выражением.
3) Для исходной строки ищем все вхождения и собираем из них выходящую строку.

Вот реализация на python-е:
import re

def clear_str(str):
  regExp = re.compile(r'[\d.]+[WC]?_O(N|FF)\b')
  return ' '.join(regExp.findAll(str))

Думаю перевести на С++ труда не составит? :)

П.С. Приведённое выражение поймает и такую последовательность: 1.2.3.4.5._ON
Непонятно нужно ли с этим бороться...

Спасибо! :)
Либо точка, либо запятая.

Приведенное выражение вполне правильное! :) Знаков минус быть не может.
AD
небольшой вопрос. А как сделать с помощью регэкспа, чтобы он находил любую последовательность символов, не принадлежащую заданной?
Litkevich Yuriy
AD, всмысле инверсии чтоли?
если да, то так [^...] где многоточие - Р.В. которое надо исключить
Tonal
Что такое "последовательность символов, не принадлежащую заданной"?
AD
Цитата(Tonal @ 1.9.2008, 13:48) *
Что такое "последовательность символов, не принадлежащую заданной"?

Я опять объяснил криво, видимо. Простите.
Я имел в виду с помощью регэкспа найти символы, не принадлежащие выражению
[\d.]+[WC]?_O(N|FF)\b.
Tonal
Ты опять криво выразился. Прочитай что-нибудь про регэкспы. :)
В регулярном выражении существует понятие класса символов. На принадлежность или непринадлежность какому-нибудь классу символ можно тестировать.
А вот принадлежность символа какому-нибудь произвольному регэкспу не определена. Например символ W и принадлпжит или нет в зависимости от того, какие символы его окружают.
Можно тестировать строку на совпадение с регуляркой, но опять же например сторока C_ON с ней не совпадёт.

Тут всё опять зависит от того, что ты хочешь сделать.
Если таки убрать из текста всё лишнее, как описывал, то алгоритм я тебе уже нарисовал. Правда т.к. в QRegExp нет findall, придётся выписать цикл явно (см. пример к "Capturing Text").

П.С. Есть ещё позитивный и негативный предпросмотр, но с ним лучше не связываться, пока не разобрался нормально. :)
AD
Практически сделал, осталось добиться последнего.
Чтобы в строке подобного рода выражения [\\d.]+[WC]?_O(N|FF)\\b можно было встретить большое количество раз. А то, он вырезает только первое подобное выражение из строки, а все сотальные, удовлетворяющие заданному регулярному выражению, затирает.
Litkevich Yuriy
Цитата(AD @ 1.9.2008, 19:57) *
, а все сотальные, удовлетворяющие заданному регулярному выражению, затирает

ЗАТИРАЕТ?
наверное правильнее сказать не возвращает.
тебе надо указатель дальше двигать по тексту, типа этого
rx.indexIn(text, pos)
AD
Извините, забыл сразу выложить код, как я реализовал. Вот сейчас выкладываю:
source

/// Удаление из имени событий всех событий, отвечающим фильтру - "Другие"
void ScrTrack::deleteOther(EVENT_NAME* evn)
{
    QRegExp rx("[\\d.|,]+[WC]?_O(N|FF)\\b");
    QRegExp reg("[\\d.|,]"), reg1("[_]"), reg2("[O]"), reg3("[N|FF]");
    QString result_string = "";
    bool t = (evn -> ev_name.find(" ") == -1) ? false : true;
    int pos = 0;
    while((pos = rx.indexIn(evn -> ev_name, pos)) != -1)
    {
        if(!t){ result_string = evn -> ev_name; break; }
        QStringList l1=rx.capturedTexts();
        for(QList<QString>::iterator iter=l1.begin(); iter!=l1.end(); ++iter)
        {
            int _if = iter -> find(reg), _if1 = iter -> find(reg1), _if2 = iter -> find(reg2), _if3 = iter -> find(reg3);
            if(iter -> find(reg) == -1 || iter -> find(reg1) == -1 || iter -> find(reg2) == -1
                || iter -> find(reg3) == -1) continue;
            result_string += *iter;
            result_string += "   ";
        }
        pos += rx.matchedLength();
    }

    evn -> ev_name = result_string.simplified();
    if(evn -> ev_name.find(rx) != -1)
    {
        if(evn -> ev_name.find(" ") == -1 && t)
        {
            double fs = getMode(evn);
            evn -> mode = fs + 100;
        }
        else if(evn -> ev_name.find(" ") != -1)
        {
            double fs = getMode(evn, true);
            evn -> mode = fs + 100;
        }
    }
}


Регэксп rx - это регэксп, который определяет те последовательности символов, которые следует оставить. Ну а далее, путем сравнений - это реализовано!
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.