Russian Qt Forum
Ноябрь 25, 2024, 14:29 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Регулярки  (Прочитано 13497 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« : Май 17, 2015, 07:34 »

Добрый день

Наконец-то (первый раз в жизни) мне понадобились регулярные выражения! Улыбающийся Нужно очень немного - "джокеры"

* - любое кол-во любых символов
? - один любое символ
- уметь искать "полные слова" (с джокерами и без)

Ладно, открываю букварь, вроде мне подходит QRegExp::Wildcard (PatternSyntax). Но тут растерялся
Цитировать
// To test a string against a wildcard expression, use exactMatch(). For example:

QRegExp rx("*.txt");
rx.setPatternSyntax(QRegExp::Wildcard);
rx.exactMatch("README.txt");        // returns true
rx.exactMatch("welcome.txt.bak");   // returns false
Вопросы

1) Так что, с Wildcard можно юзать только exactMatch, остальное не будет работать или как?
2) Во втором вызове (где returns false) мне надо чтобы находило (напр поиск "contains"). Как это сделать?
3) Чтобы искало полные слова - надо "обрамлять" \\b, правильно?

Спасибо
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #1 : Май 17, 2015, 12:16 »

1) похоже на то
2) ну придется звездочками хитрить: "*.txt*"
3) \b в Wildcard не прокатит. регулярка "\\b.+?\\.txt.*?\\b" (для QRegExp вместо знаков вопроса надо использовать setMinimal(true), QRegularExpression таким не страдает)
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Май 17, 2015, 13:31 »

1) похоже на то
2) ну придется звездочками хитрить: "*.txt*"
3) \b в Wildcard не прокатит. регулярка "\\b.+?\\.txt.*?\\b" (для QRegExp вместо знаков вопроса надо использовать setMinimal(true), QRegularExpression таким не страдает)
Поэкспериментировал, работает indexIn, QString::indexOf(QRegExp). Слово не выделяет (\\b не понимает как и любой слеш), ну не беда, сам написал.  

Тут такие проблемы

1) Строку паттерна вводит юзер, поэтому выбран WildCard. Как-то строку "транслировать" (чтобы задействовать "полный" режим) - думал, но не видно как

2) Было бы хорошо использовать "номер" (напр символ #). Пример: есть 100 объектов с именами "Sphere 1", "Sphere 2",... "Sphere 100". Или вообще имя одно "Sphere" у всех. Полезной опцией была бы возможность убрать/добавить "номера" (1..100). Как это половчее сделать?

Спасибо

Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #3 : Май 17, 2015, 14:16 »

1)
  • * -> .* (это 0 и более символов, для 1 и более — .+)
  • ? -> .
2) "Sphere ?\\d{0,3}?" — совпадет со "Sphere", "Sphere ", "Sphere123", "Sphere 999". Если жестко максимум 100, то можно что-то типа "Sphere ?(?:\\d{0,2}|100)?", но лучше погуглить Улыбающийся — уверен, таких вопросов поднималась куча
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Bepec
Гость
« Ответ #4 : Май 17, 2015, 15:00 »

Я использую deelx.h библиотечку, один ашник, поддерживает полностью все regExp, чисто сишный интерфейс.
Конечно, для себя имеется небольшая обвязочка на Qt, но вам наверно пойдёт и так Улыбающийся

PS Qt-шный regexp до пятерки отвратный Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Май 17, 2015, 15:29 »

1)
  • * -> .* (это 0 и более символов, для 1 и более — .+)
  • ? -> .
Не зрозумiв. На всяк випадок ще раз перевiрив ? - робить добре

2) "Sphere ?\\d{0,3}?" — совпадет со "Sphere", "Sphere ", "Sphere123", "Sphere 999". Если жестко максимум 100, то можно что-то типа "Sphere ?(?:\\d{0,2}|100)?", но лучше погуглить Улыбающийся — уверен, таких вопросов поднималась куча
Жестко не будет, есть варианты - напр нумерация в рамках объекта-парента или глобальная. Если просто "добавить в хвост" (убрать из хвоста) то можно без всякого RegExp. Но все так от него пищат что я аж засомневался - ну а вдруг есть "более элегантные решения" (а я тут прусь с велосипедом Улыбающийся). Напр возможен такой случай
Код:
Sphere 1 Red 
Sphere 2 Blue
...
Не то чтобы это "так уж важно" (руками переименует, не облезет), но все-таки... Неплохо бы напр так
Цитировать
Sphere # *
Это паттерн что ввел юзер. Если бы можно было выцепить "решетку" (число) чтобы только его заменить/удалить
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #6 : Май 17, 2015, 23:34 »

1) . (точка) означает любой символ в регулярном выражении, т.е. то же самое, что и ? в вайлдкарде

"Sphere # *" -> "Sphere (\\d+).*", число будет в rx.cap(1)
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Май 18, 2015, 10:46 »

Непонятки с replace. Неужели замещающая строка может быть только фиксированной? Напр такой паттерн
Цитировать
? * *
Вот я хочу заменить только первую "звездочку" не трогая остальное. Как мне это сделать? Если использовать просто " * " то это может соответствовать совсем другому контексту (во всей строке)

Спасибо
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #8 : Май 18, 2015, 10:55 »

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

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Май 18, 2015, 11:29 »

чтобы регулярка совпала со звездочкой, надо эту звездочку экранировать бэкслэшем. хотя не совсем понятно зачем для замены первого вхождения звездочки в строке использовать регулярку…
Не выходит, ставлю \\ вообще не находит. Фраза из букваря
Цитировать
In the mode Wildcard, the wildcard characters cannot be escaped. In the mode WildcardUnix, the character '\' escapes the wildcard.
Разницы между Wildcard/WildcardUnix пока не увидел. Что здесь означает "escaped"?

Спасибо
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #10 : Май 18, 2015, 14:02 »

escaped = бэкслэш перед спец. символом. значит матчнуть символ * или ? в вайлдкарде можно только в режиме WildcardUnix, дописав перед символом бэкслэш
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #11 : Май 18, 2015, 14:54 »

escaped = бэкслэш перед спец. символом. значит матчнуть символ * или ? в вайлдкарде можно только в режиме WildcardUnix, дописав перед символом бэкслэш
А каков должен быть эффект этого "матчения"?  Улыбающийся Напр
Цитировать
Sphere *
Sphere \\*
В чем разница?
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #12 : Май 18, 2015, 16:13 »

в режиме WildcardUnix первое матчнет "Sphere ляляля", а второе — "Sphere *"
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #13 : Май 18, 2015, 17:07 »

в режиме WildcardUnix первое матчнет "Sphere ляляля", а второе — "Sphere *"
Понял, спасибо. К сожалению, пользы от этого немного  Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #14 : Май 19, 2015, 11:58 »

Хотелось бы иметь возможность "удалять слово". Пример
Цитировать
arm_lo 1
arm_hi 2
Найти легко, паттерн  "arm_* *". Но как мне удалить номера (1, 2)?
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.154 секунд. Запросов: 23.