#python #string #list #split #strip
Вопрос:
Я пытаюсь разрезать и оборвать веревку. Я написал следующий код:
my_list = ['from ab1c_table in WXYnprevious in time',
'from abc3_table in MNOnprevious in time',
'from ab1_cow_table in DZMC1_IN tabncurrent in time',
'from abc4_table in ERDUncurrent in time']
my_list_1 = []
for j in my_list:
s = j.split(" ")
s.remove('from')
s.remove('in')
s.remove('in')
s.remove('time')
for k in s:
k = k.replace('current', '')
k = k.replace('previous', '')
k = k.replace('n', '')
my_list_1.append(k)
if 'tab' in my_list_1:
my_list_1.remove('tab')
print(my_list_1)
Это работает нормально, но проблема в том, что я должен удалить каждое слово отдельно. Есть ли способ сделать это в меньшем количестве строк?
Результат, который я ищу, это:
['WXY', 'MNO']
ПРАВКА 1 —
Как мне получить этот вывод —
['ab1c_table', 'WXY', 'abc3_table', 'MNO', 'ab1_cow_table', 'DZMC1_IN', 'abc4_table', 'ERDU']
Комментарии:
1. Вы можете создать список слов, которые вам нужно удалить, и повторить его.
2. Если шаблон всегда «от x в y», возможно, было бы разумнее разделить каждый элемент на пробелы, тогда целевой элемент всегда будет 4-м в списке.
3. Я думаю, что вы, вероятно, имели в виду «разделить» строку.
Ответ №1:
Я не уверен, что это то, что вы имеете в виду, но обычно регулярные выражения полезны для извлечения шаблонов из строк. Например:
import re
my_list = ['from ab1c_table in WXYnprevious in time',
'from abc3_table in MNOnprevious in time']
my_list1 = [re.findall(r" ([A-Z]{3})n", s, )[0] for s in my_list]
print(my_list_1)
Редактировать:
Вот модификация шаблона регулярных выражений, отражающая дополнительные образцы строк, предоставленные OP в комментарии ниже:
mylist = ['from ab1c_table in WXYnprevious in time',
'from abc3_table in MNOnprevious in time',
'from ab1_cow_table in DZMC1_IN tabncurrent in time',
'from abc4_table in ERDUncurrent in time']
my_list1 = [re.findall(r"_table in (S )(?:| tab)n.* in time", s)[0] for s in mylist]
print(my_list1)
Это дает:
['WXY', 'MNO', 'DZMC1_IN', 'ERDU']
Изменить 2:
_table
Шаблоны захвата версий:
import re
from itertools import chain
mylist = ['from ab1c_table in WXYnprevious in time',
'from abc3_table in MNOnprevious in time',
'from ab1_cow_table in DZMC1_IN tabncurrent in time',
'from abc4_table in ERDUncurrent in time']
my_list1 = list(chain(*[re.findall(r"from (S _table) in (S ).*?n.* in time", s)[0] for s in mylist]))
print(my_list1)
Это дает:
['ab1c_table', 'WXY', 'abc3_table', 'MNO', 'ab1_cow_table', 'DZMC1_IN', 'abc4_table', 'ERDU']
Комментарии:
1. Это было бы проблемой для «из ABC1_table» или XYZ, не являющегося ascii в верхнем регистре.
2. @tdelaney Это зависит от того, каким должен быть результат — последовательности из трех заглавных букв, трех заглавных букв, за которыми следует новая строка? Я не уверен.
3. Я тоже не уверен. Мы недостаточно знаем об этих строках, чтобы действительно сказать. Давайте посмотрим, сможет ли ОП уточнить.
4. Это может граничить с проблемой XY.
5. @tdelaney В исходном коде операции «вкладка» удаляется, поэтому, я думаю, она не должна совпадать.
Ответ №2:
Вы можете написать шаблон , который соответствует строкам и соответствует, например, предыдущему или текущему использованию (?:previous|current)
, и захватить последнюю часть первой строки в группе 1.
Сначала проверьте, есть ли совпадение, и если есть, установите новое значение в значение группы 1.
Если совпадения нет, оставьте значение неизмененным.
bfrom w in (w )nprevious in timeb
Смотрите значение группы захвата зеленым цветом в этой демонстрации регулярных выражений.
import re
pattern = r"bfrom w in (w )n(?:previous|current) in timeb"
my_list = ['from ab1c_table in WXYnprevious in time', 'from abc3_table in MNOnprevious in time']
for n, i in enumerate(my_list):
m = re.match(pattern, i)
if m:
my_list[n] = m.group(1)
print(my_list)
Выход
['WXY', 'MNO']
Ответ №3:
Как я уже предлагал ранее, я думаю, что это можно сделать намного проще с помощью простого split()
. Строки всегда следуют одному и тому же шаблону. Все, что вам нужно сделать, это разделить пробелы и удалить второй и четвертый элемент из результирующих списков.
elems = list()
for e in my_list:
# e.g., the first element becomes
# ['from', 'ab1c_table', 'in', 'WXY', 'previous', 'in', 'time']
parts = e.split()
elems.extend([parts[1], parts[3]])
print(elems)
Результат:
['ab1c_table',
'WXY',
'abc3_table',
'MNO',
'ab1_cow_table',
'DZMC1_IN',
'abc4_table',
'ERDU']
Ответ №4:
Из вопроса неясно, что является переменной в строках, но, похоже, это регулярное выражение подойдет. Цель состоит в том, чтобы сопоставить все статичное с некоторыми подстановочными знаками и группами захвата в скобках для данных, которые вы хотите получить в результате. Поскольку вам нужны две части данных в том порядке, в котором они находятся в строке, вы можете создать две группы захвата и расширить список результатов.
import re
my_list = ['from ab1c_table in WXYnprevious in time',
'from abc3_table in MNOnprevious in time',
'from ab1_cow_table in DZMC1_IN tabncurrent in time',
'from abc4_table in ERDUncurrent in time']
result = []
for value in my_list:
result.extend(re.match(r"from (. _table) in (S )", value).groups())
print(result)
Результат
['ab1c_table', 'WXY', 'abc3_table', 'MNO', 'ab1_cow_table', 'DZMC1_IN', 'abc4_table', 'ERDU']
Комментарии:
1. Это работает для этого вывода, если мне нужен немного другой вывод, как его получить? Я отредактировал вопрос
2. Обновлено для получения новых данных