Вопрос или проблема
В настоящее время у меня есть следующее в ячейке A1:
“timeZone”:”Etc/UTC”},”body”:”[~kevin.tom] [~sergio.Melle]
[~seema.item] Был ли отчет доставлен клиенту?”,”updateAuthor”:”body”:”[~katelyn.robert]\r\n\r\nЕще нет”,”updateAuthor”:
И я хочу извлечь все между
“body”:”
и
“,”updateAuthor
Как вы можете видеть в A1, если я разделю содержимое между “body”:” и “,”updateAuthor, у нас есть два результата:
[~kevin.tom] [~sergio.Melle] [~seema.item] Был ли отчет доставлен клиенту?
и
[~katelyn.robert]\r\n\r\nЕще нет”,”updateAuthor
Я хочу иметь возможность извлечь последний результат, который есть
[~katelyn.robert]\r\n\r\nЕще нет”,”updateAuthor
Я всегда буду добавлять больше в ячейку A1, и мне нужно, чтобы ячейка B1 обновлялась и извлекала последний результат, чем бы он ни был.
В настоящее время я смог придумать этот код в ячейке B1:
=MID(B1, FIND(“body”,B1)+7, FIND(“updateAuthor”, B1, FIND(“body”, B1)+1)-FIND(“body”,B1)-10)
Это работает для меня, но извлекает первый найденный результат, тогда как я хочу результаты последнего вхождения. По сути, Excel ищет слева направо, тогда как я хотел бы, чтобы он искал справа налево. Кто-нибудь знает, как это изменить, чтобы это заработало?
В настоящее время, с моим кодом в B1, я получаю это в B1:
[~kevin.tom] [~sergio.Melle] [~seema.item] Был ли отчет доставлен клиенту?
Но я хочу это:
[~katelyn.robert]\r\n\r\nЕще нет
Я пытаюсь достичь этого без использования VBA
Ладно, я просто хочу сказать, что действительно верю, что это было бы легче выяснить с помощью VBA, но мне было интересно сделать это в виде формулы.
=MID(A1,FIND("body",A1,FIND("body",A1,1)+1)+7,FIND("updateAuthor",A1,FIND("updateAuthor",A1,1)+1)-(FIND("body",A1,FIND("body",A1,1)+1)+10))
Это предполагает, что вы можете использовать “body” и “updateAuthor”, как вы сделали в предоставленной вами формуле. Если вы действительно хотите искать строковые символы с знаками препинания, такими как "body"."
, тогда найти придется что-то вроде CHAR(34) & "body" & CHAR(34) & ":" & CHAR(34)
и CHAR(34) & "," & CHAR(34) & "updateAuthor"
. Если вы сделаете это, вам также придется изменить смещения, которые добавляются (+7 и +10).
Это также предполагает, что в ячейке два и только два автора. Этот подход не будет работать, если у вас переменное количество авторов.
Синтаксис для функции Mid – MID(text,start_num,num_chars)
.
Синтаксис для функции Find – FIND(find_text,within_text,start_num)
.
FIND("body",A1,FIND("body",A1,1)+1)+7
Это дает вам начальный номер для функции Mid.
Внутренний поиск FIND("body",A1,1)
возвращает местоположение первого вхождения “body” в A1. Вам нужно добавить 1 к этому для начального номера следующего поиска, иначе вы получите то же самое местоположение. Внешний поиск затем снова смотрит на A1 для “body”, но начинает искать один символ после местоположения первого вхождения. Вам нужно добавить смещение, чтобы найти местоположение первого символа после вашего "body":"
, потому что функция поиска сообщит вам, где находится b
.
FIND("updateAuthor",A1,FIND("updateAuthor",A1,1)+1)-(FIND("body",A1,FIND("body",A1,1)+1)+10
Это дает вам количество символов для функции Mid.
Эти рекурсивные операторы поиска работают так же, как выше, чтобы найти разницу между началом информации об авторе и началом конечного тега, ","updateAuthor
, с соответствующим смещением, добавленным в конце.
Если вы пересмотрите и примете VBA, то рассмотрите следующую пользовательскую функцию:
Public Function GrabData(s As String) As String
Dim dq As String
dq = Chr(34)
arr = Split(s, "body" & dq & ":" & dq)
brr = Split(arr(UBound(arr)), dq & "," & dq & "updateAuthor")
GrabData = brr(0)
End Function
Вы можете сделать это, если можете принять ограничение по длине строки:
=MAX(IFERROR(SEARCH("body",A1,{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16, [...и т.д...],250 }),0))
Это даст вам начальную точку последнего вхождения “body” в A1, пока она меньше 250. Используйте этот трюк внутри вашей исходной формулы или в вспомогательной ячейке.
Объяснение: {range} делает это матричной формулой, ищущей с разных начальных точек, в то время как MAX() возвращает наибольший элемент в массиве. IFERROR заменяет ошибки VALUE (начальная точка слишком далеко вправо) на нули.
Если вы используете EXCEL 365, это даже проще:
=MAX(IFERROR(SEARCH("body",A1,SEQUENCE(LEN(A1),,0,1)),0))
Это создаст массив на лету, с нужной длиной.
Ответ или решение
Извлечение символов между двумя словами в Excel с поиска справа налево
Введение
Задача извлечения данных из строки в Excel может показаться сложной, особенно когда необходимо находить текст, основываясь на позициях двух ключевых фраз. В данном случае, мы столкнулись с необходимостью извлекать данные между "body" и "updateAuthor", причем последняя запись "body" должна быть извлечена, а не первая. В этом руководстве мы рассмотрим, как это сделать, не используя VBA и применяя только формулы Excel.
Понимание проблемы
Вы располагаете текстом в ячейке A1, например:
"timeZone":"Etc/UTC"},"body":"[~kevin.tom] [~sergio.Melle] [~seema.item] Was the report delivered to the client?","updateAuthor":"body":"[~katelyn.robert]\r\n\r\nNot yet","updateAuthor":
Ваша задача — извлечь текст между последним вхождением "body":" и ",updateAuthor". Это означает, что нам нужно будет искать справа налево.
Решение без использования VBA
Для выполнения поставленной задачи можно воспользоваться функцией SEARCH
в сочетании с MID
и TEXTJOIN
(в Excel 365). Поскольку ваша целевая версия Excel не подразумевает использование макросов, оптимальным решением будет применение встроенных формул.
Шаг 1: Определение позиции последнего "body"
Чтобы найти позицию последнего вхождения "body", мы можем использовать формулу массива:
=MAX(IFERROR(SEARCH("body", A1, ROW(INDIRECT("1:" & LEN(A1)))), 0))
Эта формула создает массив позиций всех вхождений "body" в строку A1 и возвращает максимальную позицию, что соответствует последнему вхождению.
Шаг 2: Извлечение текста между "body" и "updateAuthor"
Теперь, зная позицию последнего "body", мы можем извлечь нужный текст. Используем следующую формулу:
=MID(A1, MAX(IFERROR(SEARCH("body", A1, ROW(INDIRECT("1:" & LEN(A1)))), 0)) + 7, SEARCH("updateAuthor", A1, MAX(IFERROR(SEARCH("body", A1, ROW(INDIRECT("1:" & LEN(A1)))), 0))) - (MAX(IFERROR(SEARCH("body", A1, ROW(INDIRECT("1:" & LEN(A1)))), 0)) + 7))
Объяснение формулы
- SEARCH("body", A1, ROW(INDIRECT("1:" & LEN(A1)))): это создает массив позиций всех вхождений слова "body".
- MAX(…): находит максимальную позицию (то есть последнее вхождение).
- MID(A1, Starting_position, Number_of_characters): извлекает подстроку, начиная с позиции последнего "body" и заканчивая позицией перед "updateAuthor".
Ограничения
Данный метод требует, чтобы строка оставалась в определенном формате, и может потребовать адаптации, если структура изменится. Также формулы массива могут потребовать подтверждения комбинацией клавиш Ctrl + Shift + Enter в версиях Excel до 365.
Заключение
Итак, с помощью вышеприведенных формул вы сможете извлекать данные между последним вхождением "body" и "updateAuthor", не прибегая к VBA. Это решение идеально подходит для работы с динамическим текстом в Excel и позволяет обработать несколько результатов по мере их добавления.
Если у вас возникнут дополнительные вопросы или потребуется помощь с другими формулами, не стесняйтесь обращаться за помощью.