1

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

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

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

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

длина = 100

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

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

Ищу вот так:

reg.match(com)

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

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

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

Свободу узникам эппла и майкрософта!

2

>>> 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()     Возвращает позицию конца совпадения

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

3

durc, благодарю. Действительно, если задать строку в юникоде, то работает (почему-то думал, что при вводе с клавиатуры будет юникод).
Но теперь возникает вопрос: как строку (судя по всему в ascii, если верить вылезающей ошибке) перевести в юникод. В decode и encode постоянно путаюсь, но при decode никаких изменений нет, а при encode вылезает следующее:

 Консоль:
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)

Свободу узникам эппла и майкрософта!

4 (26.10.2011 23:21:27 отредактировано durc)

Ну, например

>>> 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

5

Прописал

com = unicode(com)

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

Свободу узникам эппла и майкрософта!

6

>>> 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

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

7

Решил попробовать не в модуле, а в интерпретаторе.
Результат:

 Консоль:
>>> 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)

То, что сначала задавал строку со знаком вопроса, а потом его убирал - приближение к коду модуля, т.к. знак вопроса служит для идентификации.

Свободу узникам эппла и майкрософта!

8

Примерно так

>>> 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() - Сканирует всю строку в поисках всех мест совпадений с регулярным выражением

9

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

durc пишет:

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

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

com = com[1:]
Свободу узникам эппла и майкрософта!

10

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

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

 Консоль:
['http://shop.home/image/data/cart.png" rel="icon']


Python 2.7.2

Да, у меня Ubuntu.
Нет, не глючит.

11

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

95% процентов проблем находятся между клавиатурой и стулом.

12

Fat-Zer пишет:

регулярка жадная, она ищет самое длинное соответствие...

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

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

Работает! ag

Да, у меня Ubuntu.
Нет, не глючит.