LinuxForum.Fans
Тема

[Python 2.6.6] Регулярные выражения

Автор: Osanve 12 сообщений 3666 просмотров
#201137

Здравствуйте!

Если я правильно помню регулярные выражения, то следующая строка означает:
1) Ноль или более цифр, подчеркиваний и кирилических букв
2) Далее ноль или более пробелов
3) Далее один знак равно
4) Далее ноль или более пробелов
5) Далее один или более любых символов

text
reg = ur"[_0-9а-яА-Я]* *= *.+"

Но по какой-то причине строка, которая точно удовлетворяет данному условию не находится.
Сама строка:

длина = 100

Создаю объект следующим образом:

text
reg = re.compile(reg, re.UNICODE)

Ищу вот так:

text
reg.match(com)

где com - текущая строка.

Что я делаю не так?

Заранее спасибо.

#201184

>>> import re
>>> reg = ur"[_0-9а-яА-Я]* *= *.+"
>>> reg = re.compile(reg, re.UNICODE)
>>> m = reg.match(u'длина = 100')
>>> print m
<_sre.SRE_Match object at 0x98aa838>
>>> m.group()
0: u'\u0434\u043b\u0438\u043d\u0430 = 100'
>>> print m.group()
длина = 100

И в чём проблема?
match() - Определяет, начинается ли совпадение регулярного выражения с начала строки.
Если не было найдено ни одного совпадения, то match() возвращает None. Если поиск успешен, возвращается экземпляр MatchObject, содержащий информацию о совпадении: где оно начинается и заканчивается, подстрока соответствия, и так далее.
Для MatchObject также имеется несколько методов и атрибутов, наиболее важными из которых являются:
- group() - Возвращает строку, сошедшуюся с регулярным выражением
- start() Возвращает позицию начала совпадения
- end() Возвращает позицию конца совпадения

Как то так. Подробнее.

#201188

durc, благодарю. Действительно, если задать строку в юникоде, то работает (почему-то думал, что при вводе с клавиатуры будет юникод).
Но теперь возникает вопрос: как строку (судя по всему в ascii, если верить вылезающей ошибке) перевести в юникод. В decode и encode постоянно путаюсь, но при decode никаких изменений нет, а при encode вылезает следующее:
[console]Traceback (most recent call last):
File "./main.py", line 46, in <module>
result = add_new_variable(command)
File "./main.py", line 14, in add_new_variable
com.encode('utf-8')
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 0: ordinal in range(128)[/console]

#201190

Ну, например

>>> reg = ur"[_0-9а-яА-Я]* *= *.+"
>>> reg = re.compile(reg)
>>> m = reg.match(unicode('длина = 100'))
>>> print m
<_sre.SRE_Match object at 0xb74cccd0>
>>> m.group()
1: u'\u0434\u043b\u0438\u043d\u0430 = 100'
>>> print m.group()
длина = 100
#201193

Прописал

text
com = unicode(com)

из-за того, что требуется использовать в нескольких условиях. Результат тот же, только ошибка на этой строке.

#201194

>>> com = 'длина = 100'
>>> com = unicode(com)
>>> m1 = reg.match(com)
>>> print m1
<_sre.SRE_Match object at 0xb735ecd0>
>>> m1.group()
1: u'\u0434\u043b\u0438\u043d\u0430 = 100'
>>> print m1.group()
длина = 100

Понятия не имею где у Вас грабли, проверьте ещё раз.

#201196

Решил попробовать не в модуле, а в интерпретаторе.
Результат:
[console]>>> com = "?длина = 100"
>>> print com
?длина = 100
>>> com = com[1:]
>>> print com
длина = 100
>>> com = unicode(com)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 0: ordinal not in range(128)[/console]
То, что сначала задавал строку со знаком вопроса, а потом его убирал - приближение к коду модуля, т.к. знак вопроса служит для идентификации.

#201201

Примерно так

>>> com = com.decode('utf-8')
>>> print com
?длина = 100
>>> com
u'?\u0434\u043b\u0438\u043d\u0430 = 100'
>>> import re
>>> reg = ur"[_0-9а-яА-Я]* *= *.+"
>>> reg = re.compile(reg, re.UNICODE)
>>> m = reg.match(com)
>>> m
>>> print m
None
>>> s = reg.search(com)
>>> s
<_sre.SRE_Match object at 0xa134560>
>>> print s
<_sre.SRE_Match object at 0xa134560>
>>> print s.group()
длина = 100

Напомню, match() - Определяет, начинается ли совпадение регулярного выражения с начала строки.
Но поскольку в начале знак вопроса, то пользуйтесь
search() - Сканирует всю строку в поисках всех мест совпадений с регулярным выражением

#201225

Благодарю, наконец-то заработало.

durc написал:
Но поскольку в начале знак вопроса,..

Как я уже писал, знак вопроса нужен для идентификации строки (в данном случае, если первый символ - знак вопроса, то переходим в функцию добавления переменной). После входа в функцию от знака вопроса избавляемся:

text
com = com[1:]
#226977

Уже всю клавиатуру раскрошил, однако никак не пойму, почему проскакивает вторую кавычку? smile

text
print re.findall(r'href=\"(.+)\"','<link href="http://shop.home/image/data/cart.png" rel="icon" />')

[console]['http://shop.home/image/data/cart.png" rel="icon'][/console]


Python 2.7.2

#226978

регулярка жадная, она ищет самое длинное соответствие...
если питон поддерживает ленивые регулярки, то используйте (.+?) если нет, то ([^"]+) (или как-то так)

#226982
Fat-Zer написал:
регулярка жадная, она ищет самое длинное соответствие...

А я считал, что должно останавливаться при первом совпадении..
Точно!

+? - соответствует минимальному числу повторений.

Работает! :D

Войдите или зарегистрируйтесь, чтобы ответить.