Как я могу разобрать строку из ячейки несколько раз в Excel?

4

В моей таблице есть столбец, который часто содержит строку, которую я хочу поместить в другой столбец. Эта строка может встречаться несколько раз, и я хочу поместить ВСЕ ее экземпляры в другой столбец. Столбец разделен, и я хотел бы взять соответствующую строку и до разделителя.

Пример:

Possessions
Fruit: apple, Car: Ford, Fruit: banana,
Car: Saturn,
Fruit: orange,

Я хотел бы, чтобы следующий столбец содержал:

Fruit
Fruit: apple, Fruit: banana,

Fruit: orange,

Достаточно просто найти первый экземпляр строки (новые строки для удобства чтения):

MID(A2, 
    FIND( *first instance of Fruit:* ), 
    FIND( *first comma after Fruit:* ) - FIND( *first instance of Fruit:* )
    )

Однако я мог встречаться со строкой любое количество раз и хочу поймать их все.

Кроме того, столбец уже является вычисляемым полем (ссылка на другой лист), поэтому я не могу использовать текст для столбцов для разделения на разделитель.

Любые идеи о том, как вернуть все экземпляры строки? Я бы предпочел избегать сценария VBA, если это возможно, и использовать функции рабочего листа, но если это невозможно с функциями, я открыт для VBA.

Centimane
источник
Похоже, мне нужна рекурсивная (или, возможно, в "круговой") функция Excel, которая находит и копирует, извлекает и затем объединяет ее с тем же поиском по несопоставленной строке, пока вся строка не будет исчерпана. VBA может справиться с этим, но я не уверен насчет встроенных функций Excel на основе ячеек ...
David W
Хммм ... не могли бы вы дать еще какие-нибудь рекомендации относительно того, как формально данные структурированы? То есть, глядя на ваш пример, если я отсканирую строку для слова «Фрукты:« Я могу захватить «яблоко» »достаточно легко, но, учитывая запятую, как я знаю, чтобы остановиться на« Автомобиль: »без вывода я знаю Автомобиль не фрукт? Думаю, я ищу правила форматирования / разделителя ...
David W
1
В начале всегда будет разделитель строк (например, «Fruit:») и разделитель символов в конце (например, «,») того, что я хочу записать. Таким образом, разделитель не будет появляться внутри строки, которую я пытаюсь записать, поэтому можно знать, что «Car:» не должен возвращаться, поскольку он не находится между «Fruit:» и первой запятой после «Fruit:».
Centimane
Спасибо! Это очень полезно. Решение на основе регулярных выражений сделало бы это почти тривиальным, но это было бы решение на основе VBA ...
David W

Ответы:

2

Типовое решение VBA с регулярными выражениями

Этот метод должен покрывать ваши потребности. Другие пользователи также могут использовать его для извлечения нескольких строк из заданной строки с помощью регулярных выражений.

enter image description here

  1. Откройте редактор VBA ( ALT + F11 )
  2. Вставьте новый модуль ( ! ) и вставьте в него приведенный ниже код
  3. Вернитесь в Excel и используйте эту формулу в ячейке, где вы хотите выводить

    =REGEXTRACT(A1, "Fruit: .*?,")
    

Объяснение формулы

  • =REGEXTRACT() ваша новая формула
  • A1 это ячейка, в которой находятся ваши входные данные
  • Fruit: .*?, является регулярным выражением, чтобы найти все вхождения fruit и совпадает до следующей запятой.
Function REGEXTRACT(objCell As Range, strPattern As String)

    Dim objMatches As Object
    Dim RegEx As Object
    Set RegEx = CreateObject("VBScript.RegExp")

    RegEx.IgnoreCase = True
    RegEx.Global = True
    RegEx.Pattern = strPattern

    Set objMatches = RegEx.Execute(objCell.Value)

    If objMatches.Count <> 0 Then
        For Each objMatch In objMatches
            REGEXTRACT= REGEXTRACT+ objMatch.Value
        Next objMatch
    Else: REGEXTRACT= ""
    End If

End Function

Подсказка: Смотри сзади и смотри вперед выражения не поддерживаются в регулярном выражении VB. Так что нетрудно исключить запятую через RegEx. Но это возможно через обычные строковые операции VBA.

nixda
источник
Возможно, я сказал, что хотел бы избежать опции VBA, но, учитывая беспорядок, а не чистоту его использования, я остановился на этом подходе. У меня были проблемы с использованием имени «ЭКСТРАКТ», Excel утверждал, что функция недействительна, но после переименования она работала нормально. Может ли EXTRACT конфликтовать с зарезервированным словом в excel?
Centimane
1
@ Дэйв Да, это так. В соответствии с этот список зарезервированных слов в Excel , Я изменил это на =REGEXTRACT(), Причина, по которой я не наткнулся на это, заключалась в том, что я использую локализованную версию Excel, и они также переводят эти зарезервированные слова. Очень надоедливый
nixda
может быть, вы должны добавить комментарий под своим изображением, чтобы избежать путаницы среди будущих различий в названии.
Centimane
1

Это нелепо неуклюже, но, похоже, работает. Я бы порекомендовал решение VBA, если честно.

=TRANSPOSE(LEFT(MID(A1,FIND("~~~~~~",SUBSTITUTE(A1,"Fruit:","~~~~~~",ROW(INDIRECT("1:"&(LEN(A1)-LEN(SUBSTITUTE(A1,"Fruit","")))/LEN("Fruit"))))),IFERROR(FIND(",",A1,FIND("~~~~~~",SUBSTITUTE(A1,"Fruit:","~~~~~~",ROW(INDIRECT("1:"&(LEN(A1)-LEN(SUBSTITUTE(A1,"Fruit","")))/LEN("Fruit"))))))-1,LEN(A1)-FIND("~~~~~~",SUBSTITUTE(A1,"Fruit:","~~~~~~",ROW(INDIRECT("1:"&(LEN(A1)-LEN(SUBSTITUTE(A1,"Fruit","")))/LEN("Fruit")))))+1)),IFERROR(FIND(",",MID(A1,FIND("~~~~~~",SUBSTITUTE(A1,"Fruit:","~~~~~~",ROW(INDIRECT("1:"&(LEN(A1)-LEN(SUBSTITUTE(A1,"Fruit","")))/LEN("Fruit"))))),IFERROR(FIND(",",A1,FIND("~~~~~~",SUBSTITUTE(A1,"Fruit:","~~~~~~",ROW(INDIRECT("1:"&(LEN(A1)-LEN(SUBSTITUTE(A1,"Fruit","")))/LEN("Fruit"))))))-1,LEN(A1)-FIND("~~~~~~",SUBSTITUTE(A1,"Fruit:","~~~~~~",ROW(INDIRECT("1:"&(LEN(A1)-LEN(SUBSTITUTE(A1,"Fruit","")))/LEN("Fruit")))))+1))),1000)-1))

Это формула массива, и вам нужно выбрать как минимум столько ячеек, сколько есть экземпляров «Fruit». Поэтому, если в одном столбце четыре плода, выделите четыре ячейки по ширине, введите эту формулу и подтвердите, нажав Ctrl + Shift + Enter. Если вы выберете дополнительные ячейки, то в конце начнет возвращаться ошибка, поэтому теоретически вы можете выбрать максимальное количество ячеек, которое вам понадобится для любого столбца, и выполнить автоматическое заполнение.

Редактировать: Я понял, что если есть только один фрукт, он вернет этот фрукт в каждой клетке. Я не думаю, что есть способ обойти это с этой формулой.

Он также предполагает, что у вас не будет названия фруктов длиннее 1000 символов, и что «~~~~~» не будет отображаться в вашем тексте как обычно.

Объяснение: где n - это число плодов в ячейке, формула использует FIND / SUBSTITUTE для создания массива из n элементов, в котором первое вхождение «Fruit» заменяется на «~~~~~», а затем второе. и т. д. Затем он использует MID / FIND для извлечения текста. Поскольку в Excel нет формулы «найди вхождение строки x», мы делаем сумасшедшие вещи, подобные этой. IFERROR существует для последнего Fruit, так как я предполагал, что после него может не быть запятой.

Kyle
источник
Гм, даже с excelformulabeautifier.com/ Я не смог понять формулу
nixda
хотя я не думаю, что хотел бы использовать что-то настолько громоздкое, мне это интересно, хотя для меня это возвращало только первый экземпляр «Fruit: *» во всех ячейках, в которые я его поместил A1 с $ A2, поэтому он не смотрел на мой заголовок, и я мог перетащить его).
Centimane
@ Дэйв Вы не можете перетащить формулу поверх. Вы должны выбрать все ячейки, вставить формулу в строку формул и нажать Ctrl + Shift + Enter.
Kyle
@ nixda Я добавил общее объяснение к своему ответу.
Kyle
@Kyle Это все еще приводит только к первому экземпляру "Fruit: *"
Centimane