Можно ли игнорировать строку в кавычках для python replace()
?
У меня есть такая строковая переменная:
a = "I like bananas 'I like bananas'"
Я хочу получить такой результат через replace()
:
"I like apples 'I like bananas'".
Но когда я выполняю print(a.replace("bananas", "apples"))
, результат:
"I like apples 'I like apples'".
Как сделать, чтобы replace()
игнорировала строку в кавычках?
Если вы хотите придать строковому содержимому особое значение во время замены, вам понадобится что-то вроде re
/regex. Строковые методы наивны с точки зрения содержания.
Разбить строку на ', обработать только нечетные элементы массива, собрать строку заново
a = "I like bananas 'I like bananas'"
ap = a.split("'")
ar = [ ai.replace("bananas", "apples") if i%2==0 else ai for i,ai in enumerate(ap)]
print("'".join(ar))
Это работает! Но как я могу обработать вложенную строку типа «Мне нравятся бананы, мне нравятся бананы»?
В вашем примере невозможно различить открытие и закрытие. Если бы у вас были скобки с разными символами для открытия и закрытия, вы могли бы считать. '
идентично \'
, так что вы не можете отличить друг от друга.
Единственный вариант, который у вас есть, - это разделение таким же образом и обработка только первого и последнего элементов. Может подойти для вашего варианта использования
Нет, это невозможно, вы не можете заставить replace
игнорировать эти совпадения. Вам придется кодировать собственное решение.
Вы можете использовать значение count
(необязательный параметр метода замены), чтобы указать, сколько вхождений старого значения вы хотите заменить.
Он отлично работает для обоих.
a = "I like bananas \"I like bananas\""
print(a.replace("bananas", "apples",1))
a = "I like bananas 'I like bananas'"
print(a.replace("bananas", "apples",1))
Выход:
I like apples 'I like bananas'
Вот пример регулярного выражения:
import re
text = "I like bananas 'I like bananas' 'I like also bananas'"
def replace2(orginal_text, b, c):
pattern = re.compile(r".*? (\'.*?\')") # patternt to match text inside single quotes
matches = []
for match in pattern.findall(orginal_text): # match with pattern as many times pattern is found
matches.append(match)
for match in matches:
replace_with = match.replace(b, c) # replace b with c in matched string
orginal_text = re.sub(match, replace_with, orginal_text) # replace matched text with new string
return orginal_text
result = replace2(text, "bananas", "apples")
print(result)
Он попытается найти весь текст, заключенный в одинарные кавычки. Затем заменяет старую строку (b) новой (c) из совпадений. Наконец, заменяет новые отредактированные совпадения из исходной строки.
В соответствии с вашим обновлением ваших требований в вашем ответе на gnight
a = "I like bananas 'I like \'bananas\' ' "
print (a)
Дает:
Я люблю бананы «Я люблю бананы»
поскольку \' преобразуется в ' при запуске,
то есть это то же самое, что
a = "Мне нравятся бананы 'Мне нравятся бананы' "
как говорит gnight, единственный реальный вариант - заменить только первый и последний разделы строки, которые не заключены в кавычки, т.е.
a = "I like bananas 'I like \'bananas\' ' "
ap = a.split("'")
if len(ap)>0:
ap[0]=ap[0].replace("bananas", "apples")
if len(ap)>1:
ap[-1]=ap[-1].replace("bananas", "apples")
print("'".join(ap))
что дает:
Я люблю яблоки 'Я люблю бананы'
В прошлом я писал синтаксические анализаторы для обработки экранирования тройных кавычек, которые использует Excel, и конечный автомат для отслеживания состояния кавычек, что неинтересно реализовывать, если вам в конечном итоге придется это делать.
Если вы можете привести еще несколько примеров желаемого ввода выход это может помочь
Это абсолютно возможно, это полный ответ на этот вопрос:
import re
original_str = "I like bananas 'I Love banana' somthing 'I like banana' I love banana ' I like babana again' "
pattern = r"('(.+?)')"
replaced_str = ''
quoted_strings = re.compile(pattern)
newstring = "foo"
x_start = 0
print("original_str = (", original_str+")\n")
for m in quoted_strings.finditer(original_str):
print(m.span(), m.group())
x_end, x_next = m.span()
w = original_str[x_start:x_end]
w = w.replace("banana", "apple")
replaced_str = replaced_str + w + original_str[x_end:x_next]
x_start = x_next
print(replaced_str)
выход :
original_str = ( I like bananas 'I Love banana' somthing 'I like banana' I love banana ' I like babana again' )
(15, 30) 'I Love banana'
(42, 57) 'I like banana'
(73, 95) ' I like babana again'
I like apples 'I Love banana' somthing 'I like banana' I love apple ' I like babana again'
replace
принимает аргументcount
. вы можете...replace(..., count=1)
заменить только первое вхождение. если вы хотите что-то анализировать,re
gex может помочь.