Страница 1 из 2

Регулярное выражение в параметрах подписей

Добавлено: 26 май 2016, 11:50
KartaBY
Помогите составить регулярное выражение.

Пытаюсь выввести название дороги на экран.
Использую функцию
regexp_substr( "NAME" , рег_выражение)

Дороги имеют сложное название, например:

{OH2345@УЛИЦА ПУПКИНА где

{O - служебный символ и является маркером типа дороги
Н2345 - номер дороги (вместо Н может быть любой другой символ, количество цифр от 1 до 7)
@ - служебный символ и служит для отделения номера дороги от названия улицы
УЛИЦА ПУПКИНА - собственно и есть название улица

На экран нужно вывести номер дороги
Но он должен выводится только в том случае если стоит выражение {O

У меня ничего не получается. :oops:

Re: Регулярное выражение

Добавлено: 26 май 2016, 12:40
trir
а нафиг всё пихать в одну строчку, разнесите по разным атрибутам

Re: Регулярное выражение

Добавлено: 26 май 2016, 13:35
KartaBY
Спасибо.
Очень ценный совет.
:twisted:

Re: Регулярное выражение

Добавлено: 26 май 2016, 14:23
Александр Мурый
Попробуйте такое выражение в настройках подписей:

Код: Выделить всё

CASE
WHEN "NAME" LIKE '%{O%' THEN  regexp_substr( "NAME", '[\{O](.*)@')
END
Результат будет зависеть от того, кириллическое "О" используется или латинское.

Re: Регулярное выражение

Добавлено: 26 май 2016, 14:54
Elf
Я хотел написать функцию с regex в расширенном калькуляторе полей, но столкнулся с другой проблемой:
"'ascii' codec can't encode characters in position 8-12: ordinal not in range(128) See log for more details".
В поле, вызывающем ошибку, записано: "{OH2345@УЛИЦА ПУПКИНА" (без кавычек).
Дописать строку # -*- coding: utf-8 -*- нельзя, т.к. возникает новая ошибка.

Re: Регулярное выражение

Добавлено: 26 май 2016, 15:52
Zverik
Как вы все определяете, в каком контексте задан вопрос? Perl / python / bash / sql (и какой из них) / vim / java?

Re: Регулярное выражение

Добавлено: 26 май 2016, 16:04
Эдуард Казаков
Илья, так ведь раздел про QGIS

Re: Регулярное выражение

Добавлено: 26 май 2016, 18:31
Zverik
Да, но ответы, судя по всему, идут про python.
Кстати, побороть строку с ascii codec можно, перед выводом сделав строке s.encode('utf-8').

Re: Регулярное выражение в параметрах подписей

Добавлено: 27 май 2016, 07:35
KartaBY
Александр Мурый писал(а):Попробуйте такое выражение в настройках подписей:

Код: Выделить всё

CASE
WHEN "NAME" LIKE '%{O%' THEN  regexp_substr( "NAME", '[\{O](.*)@')
END
Результат будет зависеть от того, кириллическое "О" используется или латинское.
Результат как и у меня. никакой
ScreenShot001.jpg
ScreenShot001.jpg (122 КБ) 7433 просмотра

Re: Регулярное выражение в параметрах подписей

Добавлено: 27 май 2016, 07:44
KartaBY
я вижу такую логику рендера.

если в начале слова стоит значение "{O" то
исключаем вывод на экран "{O" и все что стоит после "@" включая ее саму.
все, что стоит между этими значениями выводим
Вот с реализацией данного алгоритма не получается. То пишет что не правильно пишу код рег. выражений то ничего не выводит.

Re: Регулярное выражение в параметрах подписей

Добавлено: 27 май 2016, 09:55
Александр Мурый
Какая версия QGIS? Я пробовал на 2.14.
Было бы неплохо увидеть пример реальных данных (лучше прямо кусок слоя), потому как на строках типа "{OH2345@УЛИЦА ПУПКИНА" у меня работает.

Re: Регулярное выражение

Добавлено: 27 май 2016, 11:35
Elf
Спойлер
Отредактировал сообщение. До этого я запутался в кодировках и просил помочь разобраться.
В инструментах анализа нужно открыть расширенный калькулятор полей. Заполнить как на скрине ниже.
Снимок.JPG
Снимок.JPG (77.7 КБ) 6936 просмотров
Выбрать исходный слой. Исходный шейп у меня в кодировке utf-8.
Глобальное выражение:

Код: Выделить всё

import re
def reg(x):
x = x.encode('utf-8')
pattern = r"(^\{O.+[0-9]+@(?P<first>[А-ЯЁа-яё\s0-9-]{5,}))"
match = re.match(pattern, x)
if match:
return match.group('first').decode('utf-8')

Формула (street - имя исходного поля):

Код: Выделить всё

value = reg(<street>)

В результате расчета я выбрал новый файл в кодировке utf-8.
Результат:
результат.JPG
результат.JPG (31.42 КБ) 6936 просмотров
Александр Мурый писал(а):

Код: Выделить всё

CASE
WHEN "NAME" LIKE '%{O%' THEN  regexp_substr( "NAME", '[\{O](.*)@')
END
Этот способ проще, но я пошел другим путем, т.к. не понимаю этот язык. Кстати, что это - свой внутренний язык QGIS для полей на основе SQL? У него есть название?

Перечитал еще раз первое сообщение:
KartaBY писал(а):Пытаюсь выввести название дороги на экран.
...
На экран нужно вывести номер дороги
Я думал, что нужно вывести название дороги, а нужно номер дороги?

Re: Регулярное выражение в параметрах подписей

Добавлено: 27 май 2016, 13:13
KartaBY
QGIS 2.14

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

А вот код

Код: Выделить всё

CASE
WHEN "NAME" LIKE '%{O%' THEN  regexp_substr( "NAME", '[\{O](.*)@')
END
Заработал. (извините за кривые руки)

Правда необходимо сделать небольшую доработку. Если у меня записано только номер дороги то она не выводится. Например: {OH1234

Добавил

Код: Выделить всё

CASE
WHEN "NAME" LIKE '%{O%' THEN  regexp_substr( "NAME", '[\{O](.*)@*')
END
Получил такой результат
ScreenShot002.jpg
ScreenShot002.jpg (242.11 КБ) 7345 просмотров

Re: Регулярное выражение

Добавлено: 27 май 2016, 15:40
Александр Мурый
Elf писал(а):[ Кстати, что это - свой внутренний язык QGIS для полей на основе SQL? У него есть название?
В доках это называется "SQL-like query". Регулярные выражения похожи на питоновские, но чтобы ответить определённо, надо, видимо, лезть в исходники, а я лично не решусь. Не надо также забывать, что QGIS сделана на базе Qt, в котором есть свои приблуды для работы со строками и регул.выражениями.

Re: Регулярное выражение в параметрах подписей

Добавлено: 27 май 2016, 16:02
Александр Мурый
Попробуйте так:

Код: Выделить всё

CASE
WHEN "NAME" LIKE '%{O%' AND "NAME" LIKE  '%@%' THEN  regexp_substr( "NAME", '[\{O](.*)@')
WHEN "NAME" LIKE '%{O%' AND "NAME" NOT LIKE  '%@%' THEN  regexp_substr( "NAME", '[\{O](.*)')
END