LINUX.ORG.RU

Python и кодировки

 , ,


1

2

Доброго времени суток, уважаемые! У меня вот такая проблема: есть кортеж содержащий примерно следующую информацию:

arr = ['cn=Иванова Василий И.,OU=Manage,DC=domain,DC=loc', ' cn=Петров Иван В.,OU=Manage,DC=domain,DC=loc', ' cn=Сидоров Григорий А.,OU=Manage,DC=domain,DC=loc']

Пытаюсь при помощи регулярно выражения вытянуть из него имена пользователей:

for username in arr:
    for x in re.findall(r'[А-Яа-яёЁ .]+', str(username[0])):
        print "%s" % x

В выводе получается, что некоторые символы отображаются квадратиками, например «Шш» и «Рр». Если просто вывести кортеж, без применения регулярного выражения, его содержимое отображается нормально.

★★★

Последнее исправление: cetjs2 (всего исправлений: 1)
Ответ на: комментарий от mashina

Этот список я получаю вот таким образом:

arr = self.l.search_s("OU=%s" % department,DC=mfc51,DC=ru", ldap.SCOPE_SUBTREE, "sAMAccountName=%s" % user)

Что тут не так?

nuxster ★★★
() автор топика
Ответ на: комментарий от user_id_68054

Ошибку выдает:

Traceback (most recent call last):
  File "script-ldap.py", line 3, in <module>
    assert str is not bytes
AssertionError   

nuxster ★★★
() автор топика

ты хочешь «работать» с символами вне ASCII, при том не указывая, что строки в unicode или нужной кодовой странице

А user_id_68054 - скорее всего хотел намекнуть

assert str is not bytes
str is not bytes

ибо то что ты хочешь превратить в str тип - это просто кусок каких-то непонтных байт!

dimderbin
()
Ответ на: комментарий от dimderbin

Хорошо, это я понял. Но как мне применить те функции которые описаны в мануале, что дал mashina? Они ведь не осуществляют поиск, а мне нужно получить список всех юзверей в АД.

nuxster ★★★
() автор топика
Ответ на: комментарий от dimderbin

Да я вот как раз так и делаю. Получается на выходе:

Ши
кин Анд
ей В.
Г
ина Ма
ия В.
Боб
ов
кий Анд
ей А.
 В.
Ян
енко Дени
 А.
анд
 А.
О
е
ед
Ми
еев Федо
 А.
Че
аев Се
гей В.
.....

nuxster ★★★
() автор топика
Ответ на: комментарий от dimderbin

А user_id_68054 - скорее всего хотел намекнуть

я скорее намекнул на то что...

либо надо использовать Python-3 (а не Python-2)...

...либо использовать Python-2 но при этом стараться ни где НЕ использовать bytes (и это труднее чем может показатсья на первый взгляд :)) :-)

говоря про bytes это касается и: arr = [... ... ...]

user_id_68054 ★★★★★
()
Последнее исправление: user_id_68054 (всего исправлений: 2)
# -*- coding: utf-8 -*-

import re
arr = ['cn=Иванова Василий И.,OU=Manage,DC=domain,DC=loc', 'cn=Петров Иван В.,OU=Manage,DC=domain,DC=loc', 'cn=Сидоров Григорий А.,OU=Manage,DC=domain,DC=loc']
for username in arr:
	if type(username) != unicode:
		username=unicode(username,'utf-8')
	print '-',username
	for x in re.findall(u'[А-Яа-яёЁ .]+',username):
		print ">%s" % x


--------------------------------
- cn=Иванова Василий И.,OU=Manage,DC=domain,DC=loc
>Иванова Василий И.
- cn=Петров Иван В.,OU=Manage,DC=domain,DC=loc
>Петров Иван В.
- cn=Сидоров Григорий А.,OU=Manage,DC=domain,DC=loc
>Сидоров Григорий А.
dimderbin
()
Ответ на: комментарий от nuxster

Я не совсем понял, что мне это даст?

тебе это даст правильное решение задачи. Конкретно, там уже есть парсер DN

>>> ldap.dn.str2dn('cn=Michael Str\xc3\xb6der,dc=stroeder,dc=com',flags=ldap.DN_FORMAT_LDAPV3)
[[('cn', 'Michael Str\xc3\xb6der', 4)], [('dc', 'stroeder', 1)], [('dc', 'com', 1)]]
>>> ldap.dn.str2dn('cn=Michael Str\C3\B6der,dc=stroeder,dc=com',flags=ldap.DN_FORMAT_LDAPV3)
[[('cn', 'Michael Str\xc3\xb6der', 4)], [('dc', 'stroeder', 1)], [('dc', 'com', 1)]]

mashina ★★★★★
()
Ответ на: комментарий от mashina

Хорошо, делаю так:

result = l.search_s('ou=Manage,dc=domain,dc=loc',ldap.SCOPE_SUBTREE,'(&(objectCategory=Person)(objectClass=user))',['cn','mail'])

pattern = '[А-Яа-яЁё .]+'

for dn in result:
    users = ldap.dn.str2dn(dn[0], flags=ldap.DN_FORMAT_LDAPV3)

for username in users:
    username = username[0][1]
    print username

Печатает:

Иванов Иван И.
Manage
domain
loc    

Отлично...

Но если я пытаюсь выдерну ФИО:

for username in users:
username = username[0][1]
for x in re.findall(pattern, username):
    print "%s" % x

Выводятся только две первые буквы фамилии и все. В чем косяк? Регулярку проверил тут: https://pythex.org/, все ок.

nuxster ★★★
() автор топика
Ответ на: Программная полиция 2 от dimderbin

Это не массив, это список.

Вброс не в тему: «массив» - это конкретная структура данных, в данном случае вполне корректно, ибо реализация dynamic array. «Список» - абстрактная (по-крайней мере в контексте питона). rtfm, короче.

anonymous
()
Ответ на: комментарий от anonymous

Да какая разница как я его назвал? Из листинга понятно, что это такое. Не будем придираться к словам. С терминологией может возникать путаница, тем более при таком количестве различных определений одних вещей.

nuxster ★★★
() автор топика

В общем сделал так:

result = l.search_s('ou=Manage,dc=domain,dc=loc',ldap.SCOPE_SUBTREE,'(&(objectCategory=Person)(objectClass=user))',['cn','mail'])

for dn in result:
    users = ldap.dn.str2dn(dn[0], flags=ldap.DN_FORMAT_LDAPV3)

    for username in users:
        if username[0][0] == 'CN':
            print username[0][1]

Отдельное спасибо mashina и dimderbin !

Разъясните пожалуйста мне, почему мой вариант с регулярками не корректно работал?

nuxster ★★★
() автор топика
Ответ на: комментарий от nuxster
# -*- coding: utf-8 -*-
import re

users = ['Иванов Иван И.', u'Иванов Иван И.']
patterns = ['[А-Яа-яЁё .]+', u'[А-Яа-яЁё .]+']

for username in users:
    for pattern in patterns:
        print username, pattern
        print type(username),type(pattern)
        for x in re.findall(pattern, username):
            print ">>%s" % x
        print 
anonymous
()
Ответ на: комментарий от nuxster

Еще вот такая штука не понятна мне: если я делаю так:

for username in users:
        if username[0][0] == 'CN':
            print username[0][1]

то, username[0][1] получается строка? и его по идее без проблем можно добавить в список:

for username in users:
        if username[0][0] == 'CN':
            users.append(username[0][1])
print users

Но в этом списке оказывается не только имя пользователя:

[[('CN', '\xd0\x9c\xd0\xb8\xd1\x85\xd0\xb5\xd0\xb5\xd0\xb2 \xd0\xa4\xd0\xb5\xd0\xb4\xd0\xbe\xd1\x80 \xd0\x90.', 4)], [('OU', 'Manage', 1)], [('DC',
 'domain', 1)], [('DC', 'loc', 1)], '\xd0\x9c\xd0\xb8\xd1\x85\xd0\xb5\xd0\xb5\xd0\xb2 \xd0\xa4\xd0\xb5\xd0\xb4\xd0\xbe\xd1\x80 \xd0\x90.']  

Где косяк?

nuxster ★★★
() автор топика
Ответ на: комментарий от anonymous

Спасибо добрый человек! Вот я баклажан слепой... )))

nuxster ★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.