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

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

Страниц: [1] 2 3   Вниз
  Печать  
Автор Тема: QRegExp, два подвыражения, предваряющихся известными строками  (Прочитано 13205 раз)
Smogg
Гость
« : Июль 16, 2013, 23:22 »

Ниче не понимаю...

вот такая строчка:
https://oauth.vk.com/blank.html#access_token=17a6ab0190a8ad75c2f3dffa713c3708c6943dc1562cdee85252f33a8fdabdbc803d33e7aa841bc4e9b70&expires_in=86400&user_id=14266994

как из нее получить два Qstring'a - sAccess_token и sExpires_in?

Код:
QRegExp rx;
rx.setPattern("(?:access_token=(\\w+))(?:expires_in=(\\d+))");

if (y = rx.indexIn(s) ) {
sAccess_token = rx.cap(1);
sExpires_in = rx.cap(2);
}
не работает
« Последнее редактирование: Июль 17, 2013, 08:06 от Smogg » Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4744



Просмотр профиля WWW
« Ответ #1 : Июль 16, 2013, 23:52 »

Код
C++ (Qt)
QRegExp rx("access_token=([a-z\\d]+)&expires_in=(\\d+)");
rx.setMinimal(true);
это если порядок параметров гарантирован. и то, тут можно и обычным поиском QString::indexOf() обойтись.

если же порядок параметров неизвестен (например expires_in идет перед access_token и между ними еще что-нибудь внутри), то лучше выполнить два отдельных поиска (опять же, хоть через QString::indexOf()).
Записан

Изучением 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
thechicho
Гость
« Ответ #2 : Июль 17, 2013, 06:05 »

QRegExp rx; rx.setMinimal(true); rx.setCaseSensitivity(Qt::CaseInsensitive);
rx.setPattern("access_token=([^&]+).*&expires_in=([^&]+).*$");

и как сказал kambala лучше выполнять два отдельных поиска.

to kambala, через QString::indexOf() как это будет выглядеть?
Записан
Bepec
Гость
« Ответ #3 : Июль 17, 2013, 07:14 »

Две строки. Поиск первого вхождения, поиск второго вхождения, вырезание результатов.

Всё просто.

PS я бы indexOf использовал. Не люблю регЭкспы.
Записан
thechicho
Гость
« Ответ #4 : Июль 17, 2013, 09:30 »

Верес, код в студию.
Записан
Bepec
Гость
« Ответ #5 : Июль 17, 2013, 09:51 »

Код:
QString tmp = "https://oauth.vk.com/blank.html#access_token=17a6ab0190a8ad75c2f3dffa713c3708c6943dc1562cdee85252f33a8fdabdbc803d33e7aa841bc4e9b70&expires_in=86400&user_id=14266994";

int i1 = (tmp.indexOf("token="));
int i2 = (tmp.indexOf("&expires_in="));
int i3 = (tmp.indexOf("&user_id="));

QString sAccess_token = tmp.mid(i+6, i2);
QString sExpires_in = tmp.mid(i2+12, i3);
При желании можно ужать в две строки и без промежуточных переменных.

PS тот кто начнёт говорить про "гибкость" и "расширяемость" - огурец.
Записан
thechicho
Гость
« Ответ #6 : Июль 17, 2013, 10:57 »

tmp.mid(i+6, i2);
tmp.mid(i2+12, i3);
отжег Смеющийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Июль 17, 2013, 11:25 »

Код:
QString tmp = "https://oauth.vk.com/blank.html#access_token=17a6ab0190a8ad75c2f3dffa713c3708c6943dc1562cdee85252f33a8fdabdbc803d33e7aa841bc4e9b70&expires_in=86400&user_id=14266994";

int i1 = (tmp.indexOf("token="));
int i2 = (tmp.indexOf("&expires_in="));
int i3 = (tmp.indexOf("&user_id="));

QString sAccess_token = tmp.mid(i+6, i2);
QString sExpires_in = tmp.mid(i2+12, i3);
При желании можно ужать в две строки и без промежуточных переменных.

PS тот кто начнёт говорить про "гибкость" и "расширяемость" - огурец.
Это больше подходит для тех кто лепит 6 и 12 прямо в код (убивать надо), попутал парвметры mid, втулил нафиг не нужные скобки и никак не позаботился об обработке ошибок.
Записан
Bepec
Гость
« Ответ #8 : Июль 17, 2013, 11:45 »

thechicho, Igors - специально для вас я написал это в браузере, по памяти, максимально быстро, дабы передать примерное представление о коде.

PS переделка по умному займёт минуты полторы (90 секунд).  С отсутствием магических 6/12. Попробуйте - у вас должно получиться Веселый Займёт правда 4 строки.

PPS умение или религия не позволяет вам понять, что это пример кода?  Строит глазки

update: Igors религия не позволяет. Это я уже знаю. Так что последний вопрос к thechicho.
« Последнее редактирование: Июль 17, 2013, 11:51 от Bepec » Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4744



Просмотр профиля WWW
« Ответ #9 : Июль 17, 2013, 11:55 »

2Bepec: искать вместе с амперсандом не надо (вдруг во входной строке порядок параметров будет другой).

ну, и как уже сказали выше, магические числа — это нехорошо, лучше искомые строки засунуть в переменные и прибавлять их length()/qstrlen(). если показываешь пример, то показывай правильный, тем более что он бы занял не намного больше времени.
PS переделка по умному займёт минуты полторы (90 секунд).
Записан

Изучением 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
thechicho
Гость
« Ответ #10 : Июль 17, 2013, 11:56 »

мне просто интересно было как это выглядит с QString::indexOf(). чтобы сравнить - может действительно так проще, чем регулярками парсить Смеющийся
Записан
Bepec
Гость
« Ответ #11 : Июль 17, 2013, 11:59 »

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

PS как то помню сравнивал RegExp с indexOf - цель была парсинг параметров по разделителю. RegExp был медленнее чем indexOf почему то.
Записан
thechicho
Гость
« Ответ #12 : Июль 17, 2013, 12:07 »

QRegExp может и программу "подвесить навеки", если регулярку кривую написать. но все равно на мой взгляд лучше для парсинга, чем строковые (QString) функции.
если нужна супер-мега производительность, наверное Qt не лучший вариант для решения задачи.
Записан
Smogg
Гость
« Ответ #13 : Июль 17, 2013, 22:56 »

PS я бы indexOf использовал. Не люблю регЭкспы.
Я тоже Подмигивающий Но в данном случае правильнее и масштабируемее через регулярности, безотносительно моих симпатий(

rx.setPattern("access_token=([^&]+).*&expires_in=([^&]+).*$");
Что тут происходит пo моему разумению... :
  • Отсутствие ^ в начале паттерна говорит, что перед первым соответствие регэкспу может быть что и сколько угодно.
  • access_token=
    Потом прямо вписанный access_token= означает именно такой порядок символов.
  • ([^&]+)
    Дальше открываются скобки и они означают начало нового экземпляра поиска по регэкспу и поэтому можно опять использовать ^?
    Как прочитал и запомнил, в квадратных скобках может быть перечисление без пробелов вариантов вхождений или интервалы через тире. Амперсанд же по справке не относится к служебным символам. Что & тут означает?
    + - как минимум одно вхождение предыдущего выражения.
  • Потом очередное подвыражение: .*&expires_in
    каковое означает вхождение любого символа не важно сколько раз, пока не найдется очередной plaintext &expires_in, который начинается с &, использованный совсем в другом смысле в квадратных скобках...
  • ([^&]+)
    дальше не понятный мне дзен в скобка
  • .*$
    есть ли необходимость явно указывать, что до конца строки может быть еще что-то?

Еще один вопрос:
Как складывать в QStringList несколько соответствий одному и тому же регекспу?
Записан
tester64
Гость
« Ответ #14 : Июль 17, 2013, 23:21 »

Если очерёдность известна, то например так:
Код
C++ (Qt)
QRegExp rx(".+(?:access_token=([0-9a-f]+)(?:&|$)).*(?:expires_in=(\\d+)(?:&|$)).*");
if (rx.exactMatch(s)) { sAccess_token = rx.cap(1); sExpires_in = rx.cap(2); }
Записан
Страниц: [1] 2 3   Вверх
  Печать  
 
Перейти в:  


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