我想用不同的字符替换字符串中的每个字符,并在字母表中移位。我在下面的例子中移动了2,所以a - > c,b - > d等。
我正在尝试使用正则表达式和sub
函数来完成此操作,但我收到了错误。
这是我的代码:
p = re.compile(r'(\w)')
test = p.sub(chr(ord('\\1') + 2), text)
print test
其中变量text
是输入字符串。
我收到了这个错误:
TypeError:ord()需要一个字符,但找到长度为2的字符串
我认为问题在于我在文字字符串“\ 1”上调用ord
函数,而不是在正则表达式匹配的\w
字符上调用。这样做的正确方法是什么?
答案 0 :(得分:4)
它不会像这样工作。 Python首先运行chr(ord('\\') + 2
,然后将结果传递给p.sub
。
您需要将其放在单独的函数中或使用匿名函数(lambda):
p = re.compile(r'(\w)')
test = p.sub(lambda m: chr(ord(m.group(1)) + 2), text)
print test
或者更好的是使用maketrans
而不是正则表达式:
import string
shift = 2
t = string.maketrans(string.ascii_lowercase, string.ascii_lowercase[shift:] +
string.ascii_lowercase[:shift])
string.translate(text, t)
答案 1 :(得分:2)
完整版
def shouldShift(char):
return char in string.lowercase
def caesarShift(string, n):
def letterToNum(char):
return ord(char)-ord('a')
def numToLetter(num):
return chr(num+ord('a'))
def shiftByN(char):
return numToLetter((letterToNum(char)+n) % 26)
return ''.join((shiftByN(c) if shouldShift(c) else c) for c in string.lower())
<强>一衬垫强>
如果你真的想要一个单行,那就是这个,但我觉得它更加丑陋:
''.join(chr((ord(c)-ord('a')+n)%26 + ord('a')) for c in string)
<强>演示强>
>>> caesarShift(string.lowercase, 3)
'defghijklmnopqrstuvwxyzabc'
答案 2 :(得分:1)
尝试使用列表推导:
input = 'ABC'
''.join(chr(ord(c)+2) for c in input)
> 'CDE'
它比使用正则表达式更简单。
答案 3 :(得分:0)
def CaesarCipher(s1,num):
new_str = ''
for i in s1:
asc_V = ord(i)
if asc_V in range(65, 91):
if asc_V + num > 90:
asc_val = 65 + (num - 1 - (90 - asc_V))
else:
asc_val = asc_V + num
new_str = new_str + chr(asc_val)
elif (asc_V in range(97, 123)):
if asc_V + num > 122:
asc_val = 97 + (num - 1 - (122 - asc_V))
else:
asc_val = asc_V + num
new_str = new_str + chr(asc_val)
else:
new_str = new_str + i
return new_str
print(CaesarCipher(“HEllo”,4))
print(CaesarCipher(“xyzderBYTE”,2))