Problem with lower() for unicode strings in russian

A

Alexey Moskvin

Hi!
I have a set of strings (all letters are capitalized) at utf-8,
russian language. I need to lower it, but
my_string.lower(). Doesn't work.
See sample script:
# -*- coding: utf-8 -*-
[skip]
s1 = self.title
s2 = self.title.lower()
print s1 == s2

returns true.
I have no problems with lower() for english letters:, or with
something like this:
u'russian_letters_here'.lower(), but I don't need constants, I need to
modify variables, but there is no any changs, when I apply lower()
function to mine strings.
 
D

Diez B. Roggisch

Alexey said:
Hi!
I have a set of strings (all letters are capitalized) at utf-8,
russian language. I need to lower it, but
my_string.lower(). Doesn't work.
See sample script:
# -*- coding: utf-8 -*-
[skip]
s1 = self.title
s2 = self.title.lower()
print s1 == s2

returns true.
I have no problems with lower() for english letters:, or with
something like this:
u'russian_letters_here'.lower(), but I don't need constants, I need to
modify variables, but there is no any changs, when I apply lower()
function to mine strings.

Can you give a concrete example? I doubt that there is anything
different between lowering a unicode object given as literal or acquired
somewhere else. And because my russian skills equal my chinese - total
of zero - I can't create a test myself :)
 
M

Martin v. Löwis

I have a set of strings (all letters are capitalized) at utf-8,

That's the problem. If these are really utf-8 encoded byte strings,
then .lower likely won't work. It uses the C library's tolower API,
which works on a byte level, i.e. can't work for multi-byte encodings.

What you need to do is to operate on Unicode strings. I.e. instead
of

s.lower()

do

s.decode("utf-8").lower()

or (if you need byte strings back)

s.decode("utf-8").lower().encode("utf-8")

If you find that you write the latter, I recommend that you redesign
your application. Don't use byte strings to represent text, but use
Unicode strings all the time, except at the system boundary (where
you decode/encode as appropriate).

There are some limitations with Unicode .lower also, but I don't
think they apply to Russian (specifically, SpecialCasing.txt is
not considered).

HTH,
Martin
 
K

konstantin

Martin, thanks for fast reply, now anything is ok!

Alexey,

if your strings stored in some text file you can use "codecs" package
import codecs
handler = codecs.open('somefile', 'r', 'utf-8')
# ... do the job
handler.close()

I prefer this way to deal with russian in utf-8.

Konstantin.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top