python : извлеките вложенную строку после разделителя

#python

Вопрос:

Я хотел бы извлечь вложенную строку из начальной строки при последнем появлении разделителя:

пример

 str1= "aaaa.{i}.bbbb.{i}.cccc.{i}."

str2= "aaaa.bbbb.{i}.cccc.{i}."

str3= "aaaa.bbbb.cccc.{i}."
 

ожидаемый результат таков:

cccc

Я использую следующий скрипт на python:

 res = str3.rsplit('.{i}.', 2)[1]
print(res)
 

но для str3 сценария не отображается ожидаемый результат cccc !

Комментарии:

1. Это забавный разделитель. На str3 вас нет другого .{i}. , который разбивает строку в нужном вам месте. Похоже, что вместо этого вы хотите разделить строку с помощью разделителя . , а затем (или… до) удалить вхождения .{i}. .

2. Вы действительно хотите cccc получить результат во всех трех случаях? Вам должно быть ясно, что это невозможно при разделении одним разделителем. Может быть, вы недостаточно ясно объяснили, в чем ваша реальная проблема?

Ответ №1:

Невозможно выполнить (r)split все три строки только один раз и получить результат 'cccc' во всех случаях. Я думаю, вы это знаете, но вы неправильно перевели свою идею на Python.

Вы можете rsplit дважды:

 >>> str1.rsplit('.{i}.')[-2].rsplit('.')[-1]
'cccc'
>>> str2.rsplit('.{i}.')[-2].rsplit('.')[-1]
'cccc'
>>> str3.rsplit('.{i}.')[-2].rsplit('.')[-1]
'cccc'
 

или используйте регулярное выражение:

 >>> import re
>>> pattern = re.compile(r'^.*.([^.] ).{i}.

Хотя я ожидал бы, что решение с регулярным выражением будет гораздо менее эффективным, чем подход с двойным разделением, но я не измерял. Я также не занимался обработкой ошибок.


Ответ №2:

Вам нужно что-то вроде:

 str1= "aaaa.{i}.bbbb.{i}.cccc.{i}."

str2= "aaaa.bbbb.{i}.cccc.{i}."

str3= "aaaa.bbbb.cccc.{i}."


def last_occur(st):
    st = st.split('.{i}.')
    st = list(filter(None, st))
    return st[-1]
 

Это также удалит пустые строки в случае, если у вас есть только одно разделение.

Результат:

 last_occur(str1) --> cccc
last_occur(str2) --> cccc
last_occur(str3) --> aaaa.bbbb.cccc
 

Комментарии:

1. OP, похоже, ожидает cccc вывода для всех строк дерева. Мы знаем, что это невозможно просто разделить...

2. Я понимаю, так что, вероятно, здесь нужно какое-то регулярное выражение.

3. ...или ты разделяешься дважды

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

5. Это также удалит пустые строки -я думаю, что это заслуживает небольшого разъяснения. filter(None,...) на самом деле это не говорит само за себя

)
>>> re.match(pattern, str1).group(1)
'cccc'
>>> re.match(pattern, str2).group(1)
'cccc'
>>> re.match(pattern, str3).group(1)
'cccc'
Хотя я ожидал бы, что решение с регулярным выражением будет гораздо менее эффективным, чем подход с двойным разделением, но я не измерял. Я также не занимался обработкой ошибок.

Ответ №2:

Вам нужно что-то вроде:


Это также удалит пустые строки в случае, если у вас есть только одно разделение.

Результат:


Комментарии:

1. OP, похоже, ожидает cccc вывода для всех строк дерева. Мы знаем, что это невозможно просто разделить…

2. Я понимаю, так что, вероятно, здесь нужно какое-то регулярное выражение.

3. …или ты разделяешься дважды

4. Я думаю, что вы поступаете правильно, если мы отнесемся к описанию и названию более серьезно, чем якобы ожидаемый результат. Но все это выглядит для меня довольно противоречиво…

5. Это также удалит пустые строки -я думаю, что это заслуживает небольшого разъяснения. filter(None,...) на самом деле это не говорит само за себя