开发者

Replace each char in a multi-line string except space and \r \n, how?

A multi-line string, e.g.

abc 123
456 def

wanted result (ordinal + 2):

cde 345
678 fgh

if I use:

text = "abc 123\n456 def"
add开发者_开发知识库2=''.join(chr(ord(c)+2) for c in text)
print text
print add2

the space and \r \n will also be replaced, how can I add the exception of not including space, \r or \n in the 2nd line of code.

p.s. it's follow up to this question.


Your other question suggests that you might be translating a very long string (a PDF file). In that case, using the string translate method will be quicker than doing a character-by-character for-loop over the string:

test.py:

import string

infile='filename.pdf'
outfile='newfile.pdf'

with open(infile,'r') as f:
    text=f.read()

def using_translate():
    start_chars=''.join(chr(n) for n  in range(256) if not chr(n).isspace())
    end_chars=''.join(chr((ord(c)+2)%256) for c in start_chars)
    table = string.maketrans(start_chars,end_chars)
    return text.translate(table)

def using_for_c_in_text():
    return ''.join(chr((ord(c) + 2)%256) if not c.isspace() else c for c in text)

This shows the results of a timeit run using a 1M pdf file:

# % python -mtimeit -s"import test" "test.using_for_c_in_text()"
# 10 loops, best of 3: 821 msec per loop
# % python -mtimeit -s"import test" "test.using_translate()"
# 100 loops, best of 3: 4.36 msec per loop

PS: Many answers (including mine at one point) used chr(ord(c) + 2). This throws a TypeError if ord(c)+2>=256. To avoid the TypeError, you could use chr((ord(c) + 2)%256).


You can simply check if the character is alphanumeric and keep the original character otherwise:

add2 = ''.join(chr(ord(c)+2) if c.isalnum() else c for c in text)

Please note that applying this to some characters (such as 'y', 'z', '9', '0' etc) might not yield what you expect. I.e., 'y' will not become 'a', but '{'.


slower than @Roger's solution but filters all whitespace:

>>> text = "abc 123\n456 def"
>>> ''.join(chr(ord(c) + 2) if not c.isspace() else c for c in text)
'cde 345\n678 fgh'

same as above but only bumps up alphanumerics:

>>> text = "abc 123\n456 def"
>>> ''.join(chr(ord(c) + 2) if c.isalnum() else c for c in text)
'cde 345\n678 fgh'


add2 = ''.join(chr(ord(c) + 2) if c not in "\n\r " else c for c in text)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜