2015-07-17 10 views
1

Хотел бы посмотреть, пойду ли я в правильном направлении. Я должен изменить все, кроме последних четырех символов строки, на #. Пока у меня есть две идеи.Изменение частей строки с '#'

Первый один:

def maskify(cc): 
    cc = raw_input("Enter passcode: ") 
    n = len(cc) 
    cc.replace(cc[0:n-4], #) # this one gives me the unexpected EOF while parsing error 

Второй один (я думаю, что это один ближе, потому что это, мол, нужен алгоритм):

def maskify(cc): 
    cc = raw_input("Enter passcode: ") 
    n = len(cc) 
    for i in range (0, n-4): # i think a for loop would be good but i don't know how i'm going to use it yet 
     cc.replace(     #not entirely sure what to put here 
    pass       
+1

Пример был бы лучше –

+2

Обратите внимание, что строковый литерал '' # ''не совпадает с символом' # ', который, как вам отчетливо известно, * * начинает встроенный комментарий **. – jonrsharpe

+0

@jonsharpe спасибо за это, пропустили его раньше – zhangyi

ответ

2

Проблема в первом примере, что # в кавычках. Вам нужно изменить его на '#', иначе он будет разобран как начало комментария, а прилагаемая скобка будет частью этого комментария. Хотя, это только исправит ошибку синтаксического анализа.

Проблема со строками заключается в том, что вы не можете изменять символы внутри них (это immutable). Общим способом обойти это является создание массива строки, изменение символов, которые вы хотите изменить, а затем преобразование массива обратно в строку (часто с использованием ''.join(character_array)). Попробуй это!

2
cc = raw_input("Enter passcode: ") 
cc = ''.join(('#' * (len(cc) - 4), cc[-4:])) 
+1

'raw_input()' возвращает 'str', поэтому ваш Вторая строка является избыточной. –

+1

Вместо 'cc [len (cc) - 4:]' вы можете сделать 'cc [-4:]'. И тогда вы можете избавиться от теста 'if', потому что' n * '#' 'создает пустую строку, если n <= 0. –

0

Строковый литерал '#' не совпадает с символом #, который запускает встроенный комментарий.

def maskify(cc): 
    cc = raw_input("Enter passcode: ") 
    mask = '#'*(len(cc)-4) 
    return mask + cc[-4:] 
+0

Это не работает по двум причинам. Во-первых, строки Python неизменяемы, поэтому вы не можете изменить их на месте: вы должны назначить возвращаемое значение '.replace()' '' cc'. Во-вторых, по умолчанию '.replace() 'выполняет множественные замены; например, посмотреть, что он делает с 'flipflop'. Вы можете исправить это, передав необязательный аргумент _count_ в [.replace()] (https://docs.python.org/2/library/stdtypes.html#str.replace). В будущем, _please_ тестовый код перед отправкой. –

+0

Это работает _does_. Но теперь ваш ответ по сути является дубликатом, опубликованным ранее [bebop] (http://stackoverflow.com/a/31472879/4014959), кроме добавленной информации о правильном цитировании строковых литералов. –

1

Просто немного изменить свой код:

cc = raw_input("Enter passcode: ") 
n = len(cc) 
c="" 
for i in range(0, n-4): # i think a for loop would be good but i don't know how i'm going to use it yet 
    c+="#"    #not entirely sure what to put here 
cc= c+cc [-4:] 
print cc 

выход:

Enter passcode: kased 
#ased 
+0

почти. пробовал с более входом и он пошел что-то вроде: Введите код доступа: текст здесь #here ## здесь ### здесь #### здесь ##### здесь он должен просто return '##### здесь' – zhangyi

2

Как насчет следующего?

def maskify() : 
    cc = input("Enter passcode: ") 
    mask = '#'*(len(cc)-4) 
    return mask + cc[-4:] 

Я не знаю, как поток остальной части вашей программы работает, но я сомневаюсь, следует ли вам запрашивая raw_input внутри этой функции. Вы можете решить, что в зависимости от ваших потребностей. Альтернативой будет выглядеть примерно так:

def maskify(cc) : 
    return '#'*(len(cc)-4) + cc[-4:] 

myInput = input("Enter passcode: ") 
maskedInput = maskify(myInput) 
  • NB: python2 использует raw_input вместо input
+0

попробовал это сейчас. избавился от ошибки EOF, но вместо этого получил ошибку «raw_input is not defined». спасибо, не знал, что вы можете сделать «#» * (len (cc) -4) при смене частей строки – zhangyi

+2

, какая версия python? В python3, 'raw_input' был изменен на' input' – reynoldsnlp

+0

python3, забыл, что я больше не использовал свою более старую версию. Извините – zhangyi

0

Как уже упоминалось # начинает комментарий. Если вам нужна строка, содержащая хэш, вам нужно сделать '#'.

Как упоминал Андре Ласло, строки Python неизменяемы, поэтому невозможно для операции с строкой для изменения содержимого строки. Таким образом, метод str.replace() не может изменить исходную строку: ему нужно создать новую строку, которая является модифицированной версией исходной строки.

Так что, если вы

cc = 'cat' 
cc.replace('c', 'b') 

тогда Python будет создать новую строку, содержащую 'bat', который получил бы выбросить, потому что вы не сохраните его в любом месте.

Вместо этого, вам нужно сделать что-то вроде

cc = 'cat' 
cc = cc.replace('c', 'b') 

Это отбрасывает исходный объект строки 'cat', который был связан с именем cc и связывает новую строку 'bat' к нему.

Наилучший подход (AFAIK) к решению вашей проблемы приведен в ответе bebop. Вот немного модифицированная версия кода bebop, показывающая, что она корректно обрабатывает короткие строки (включая пустую строку).

def maskify(s) : 
    return '#' * (len(s) - 4) + s[-4:] 

alpha = 'abcdefghij' 
data = [alpha[:i] for i in range(len(alpha)+1)] 

for s in data: 
    print((s, maskify(s))) 

выход

('', '') 
('a', 'a') 
('ab', 'ab') 
('abc', 'abc') 
('abcd', 'abcd') 
('abcde', '#bcde') 
('abcdef', '##cdef') 
('abcdefg', '###defg') 
('abcdefgh', '####efgh') 
('abcdefghi', '#####fghi') 
('abcdefghij', '######ghij') 
1

Следующее решение делает предположение, что это будет иметь использование типа безопасности, в качестве таких кодов связи 4-й или меньшего количества символов должны быть просто хэшируется, в противном случае кто-то будет знать, полный код доступа.

def maskify(cc): 
    if len(cc) < 9: 
     split = [0,1,2,3,4,4,4,4,4][len(cc)] 
    else: 
     split = len(cc) - 4 

    return "#" * split + cc[split:] 

for length in range(1,12): 
    test = string.lowercase[:length] 
    print "%s > %s" % (test, maskify(test)) 

дают следующие результаты:

a > # 
ab > ## 
abc > ### 
abcd > #### 
abcde > ####e 
abcdef > ####ef 
abcdefg > ####efg 
abcdefgh > ####efgh 
abcdefghi > #####fghi 
abcdefghij > ######ghij 
abcdefghijk > #######hijk 

Если короткое хэш не требуется, то просто изменить массив следующим образом, чтобы получить другие результаты:

def maskify(cc): 
    if len(cc) < 9: 
     split = [0,0,0,0,0,1,2,3,4][len(cc)] 
    else: 
     split = len(cc) - 4 

    return "#" * split + cc[split:] 

Давать:

a > a 
ab > ab 
abc > abc 
abcd > abcd 
abcde > #bcde 
abcdef > ##cdef 
abcdefg > ###defg 
abcdefgh > ####efgh 
abcdefghi > #####fghi 
abcdefghij > ######ghij 
abcdefghijk > #######hijk 
0

Прежде всего строки неизменяемы (они не могут быть изменены) после создания - поэтому вы не можете изменить значение cc с помощью replace(). Для того, чтобы изменить все части строки, за исключением последних четырех, сделайте следующее:

def doso(text): 
    assert len(str(text))>4, 'Length of text should be >4' 
    ctext=str(text).replace(str(text)[:(len(str(text))-4)],'#'*(len(str(text))-4)) 
    print(ctext) 

>>>doso(123) prints 'Length of text should be >4' because len(text)== 3 which is what we expect 

Hovever,

>>>doso(12345678) prints #####6789 which is exactly what we expect 

Примечание: Ведение '#' * (Len (ул (текст)) - 4)) учитывает количество символов, которые мы хотим заменить

Смежные вопросы