#python #regex
#python #регулярное выражение
Вопрос:
У меня есть строка со списком переменных / значений, например.
string = " var1 = 20, var2 = hello var3 =345.34 var4 = I have lost
2,5 billions, var5 = Bill"
разделение кортежей может быть «,» или любым количеством пробелов, идентификация кортежей всегда «=»
проблема заключается в том, что некоторые значения содержат описательную строку с запятыми в качестве разделителя тысяч или, на худой конец, в качестве разделителя цифр.
Я попытался использовать последовательность re.sub и re.findall с регулярным выражением python, но я не могу правильно разделить кортеж var4, приведенный ниже кода :
import re
string = " var1 = 20, var2 = hello var3 =345.34 var4 = I lost 2,5
billions, var5 = Bill"
t = re.sub('(=s )', '=', string)
t = re.sub('(s =)', '=', t)
result = re.findall("[A-Za-z0-9(,)=.] ", t)
print(result)
['var1=20,', 'var2=hello', 'var3=345.34', 'var4=I', 'lost', '2,5',
'billions,', 'var5=Bill']
Мой ожидаемый результат
['var1=20', 'var2=hello', 'var3=345.34', 'var4=I lost 2,5 billions', 'var5=Bill']
Комментарии:
1. Есть ли разрыв строки в строке? Или вы имели в виду написать
"""..."""
? Или это просто форматирование в вопросе?2. Нет, в строке нет разрыва строки, это просто моя проблема с форматированием при отправке вопроса, извините
3. Хорошо, попробуйте
result = re.split(r's (?=w =)', re.sub(r's*=s*', '=', s.strip()))
Ответ №1:
Вы можете использовать
re.split(r',?s (?=w =)', re.sub(r's*=s*', '=', s.strip()))
re.sub(r's*=s*', '=', s.strip())
Удалит пробелы вокруг =
после удаления начальных / конечных пробелов в строке и r',?s (?=w =)'
с re.split
разделит строку на необязательную запятую, затем 1 или более пробелов, за которыми следуют символы 1 word, а затем =
.
Смотрите демонстрацию Python:
import re
s = " var1 = 20, var2 = hello var3 =345.34 var4 = I lost 2,5 billions, var5 = Bill"
result = re.split(r",?s (?=w =)", re.sub(r's*=s*', '=', s.strip()))
print(result)
# => ['var1=20', 'var2=hello', 'var3=345.34', 'var4=I lost 2,5 billions', 'var5=Bill']
Комментарии:
1. Хорошо, проблема в том, что кортежи name =value могут быть разделены в строке запятыми или любым количеством пробелов, и запятые также могут быть внутри значения, например, var4 value -> «Я потерял 2,5 миллиарда» , но разделение от var4 и var5 тоже запятая …. миллиарды, var5 = Счет
2. @Alex Поделитесь строкой, которую у вас возникли проблемы с разделением при моем подходе, и укажите ожидаемый результат.
3. string = » var1 = 20, var2 = привет, var3 = 345,34, var4 = я потерял 2,5 миллиарда, var5 = Счет»
4. результат = [‘var1= 20’, ‘var2= привет’, ‘var3= 345.34’, ‘var4= я потерял 2,5 миллиарда’, ‘var5 = Счет’] как вы видите, var4 не содержит запятой в конце, потому что разделение между var4 и var5 — это запятая плюс пробел
5. @Alex обновлен, чтобы соответствовать этим новым требованиям.
Ответ №2:
Если каждый элемент, который вы хотите извлечь, начинается с var
, вы могли бы использовать этот факт следующим образом:
import re
string = " var1 = 20, var2 = hello var3 =345.34 var4 = I have lost 2,5 billions, var5 = Bill"
vars = re.findall(r'var.*?(?=var|$)',string)
print(vars) # ['var1 = 20, ', 'var2 = hello ', 'var3 =345.34 ', 'var4 = I have lost 2,5 billions, ', 'var5 = Bill']
Я использовал так называемый положительный прогноз (своего рода утверждение нулевой длины), поэтому findall
ищет подстроки, за которыми следует var
или конец str
( $
). Как вы могли видеть, str
s внутри vars
все еще нуждаются в некоторой очистке. Сначала удалите конечные пробелы:
vars = [i.strip(' ') for i in vars]
print(vars) # ['var1 = 20,', 'var2 = hello', 'var3 =345.34', 'var4 = I have lost 2,5 billions,', 'var5 = Bill']
Теперь ваш пример для меня неясен — я не знаю, хотите ли вы сохранить конечные ,
значения, как в var1 = 20,
, или удалить их, как в var4=I lost 2,5 billions
— поэтому я сохраняю ,
значения, поскольку они отмечают, что они могут быть удалены таким же образом, как показано для пробелов.
Наконец, чтобы удалить пробелы вокруг, =
вы можете использовать re.sub
следующий способ:
vars = [re.sub(r' *= *','=',i,1) for i in vars]
print(vars) #['var1=20,', 'var2=hello', 'var3=345.34', 'var4=I have lost 2,5 billions,', 'var5=Bill']
Обратите внимание, что 1
in re.sub
является преднамеренным, поэтому произойдет только 1
замена — так что пробелы будут удалены только вокруг первого =
в каждом элементе vars
. Вы можете отказаться от этого, 1
если вы уверены, что в каждом элементе не более 1 =
.
Комментарии:
1. Я хочу сохранить запятую, если она находится внутри значения переменной кортежа = value, например, в «2,5» значения var4, но не в том случае, если она находится в конце кортежа в качестве разделителя.
2. Нет, имя переменной изменяется в строке, единственной константой является разделение имени переменной и значения, и это <любое количество пробелов> = <любое количество пробелов> разделителем в моем примере являются пробелы или запятая, но пробелы и запятые также могут быть внутри значения