Реглекс для вилучення рядків в Excel (один або всі збіги)

  • Поділитися Цим
Michael Brown

Зміст

У цьому уроці ви дізнаєтеся, як використовувати регулярні вирази в Excel для пошуку та вилучення підрядків, що відповідають заданому шаблону.

Microsoft Excel надає ряд функцій для вилучення тексту з комірок. Ці функції можуть впоратися з більшістю завдань по вилученню рядків на ваших робочих аркушах. Більшістю, але не з усіма. Коли текстові функції спотикаються, на допомогу приходять регулярні вирази. Стривайте... В Excel немає функцій RegEx! Правда, немає вбудованих функцій. Але ніщо не заважає вам використовувати свої власні :)

    Excel VBA Regex функція для вилучення рядків

    Щоб додати користувацьку функцію Regex Extract в ваш Excel, вставте наступний код в редакторі VBA. Для того, щоб включити регулярні вирази в VBA, ми використовуємо вбудований об'єкт Microsoft RegExp.

    Public Function RegExpExtract(text As String , pattern As String , Optional instance_num As Integer = 0, Optional match_case As Boolean = True ) Dim text_matches() As String Dim matches_index As Integer On Error GoTo ErrHandle RegExpExtract = "" Set regex = CreateObject ( "VBScript.RegExp" ) regex.pattern = pattern regex.Global = True regex.MultiLine = True If True = match_case Thenregex.ignorecase = False Else regex.ignorecase = True End If Set matches = regex.Execute(text) If 0 <matches.Count Then If (0 = instance_num) Then ReDim text_matches(matches.Count - 1, 0) For matches_index = 0 To matches.Count - 1 text_matches(matches_index, 0) = matches.Item(matches_index) Next matches_index RegExpExtract = text_matches Else RegExpExtract = matches.Item(instance_num - 1) EndIf End If Exit Function ErrHandle: RegExpExtract = CVErr(xlErrValue) End Function

    Якщо у вас мало досвіду роботи з VBA, вам може стати в нагоді покрокова інструкція: Як вставити код VBA в Excel.

    Примітка: для того, щоб функція працювала, обов'язково збережіть файл у форматі робоча книга з підтримкою макросів (.xlsm).

    Синтаксис RegExpExtract

    На сьогоднішній день, на жаль, це не так. RegExpExtract шукає у вхідному рядку значення, що відповідають регулярному виразу, і витягує один або всі збіги.

    Функція має наступний синтаксис:

    RegExpExtract(text, pattern, [instance_num], [match_case])

    Де:

    • Текст (обов'язково) - текстовий рядок для пошуку.
    • Візерунок (обов'язково) - регулярний вираз для пошуку. При поданні безпосередньо у формулі шаблон слід брати у подвійні лапки.
    • Номер примірника (необов'язково) - серійний номер, який вказує на те, який екземпляр витягувати. Якщо не вказано, повертає всі знайдені збіги (за замовчуванням).
    • Match_case (необов'язковий) - визначає, чи зіставляти або ігнорувати регістр тексту. Якщо TRUE або опущено (за замовчуванням), виконується зіставлення з урахуванням регістру, якщо FALSE - без урахування регістру.

    Функція працює у всіх версіях Excel 365, Excel 2021, Excel 2019, Excel 2016, Excel 2013 та Excel 2010.

    4 речі, які варто знати про RegExpExtract

    Для ефективного використання функції у вашому Excel, є кілька важливих моментів, на які слід звернути увагу:

    1. За замовчуванням функція повертає всі знайдені збіги в сусідні комірки, як показано в цьому прикладі. Щоб отримати конкретний випадок, введіть відповідне число в поле instance_num аргумент.
    2. За замовчуванням функція з урахуванням особливостей конкретного випадку Для нечутливого до регістру зіставлення встановіть значення match_case Через обмеження VBA нечутлива до регістру конструкція (?i) не буде працювати.
    3. Якщо в валідний шаблон не знайдено функція не повертає нічого (пустий рядок).
    4. У разі, якщо шаблон недійсний виникає помилка #VALUE!

    Перш ніж почати використовувати цю користувацьку функцію на своїх аркушах, потрібно зрозуміти, на що вона здатна, чи не так? Наведені нижче приклади охоплюють кілька поширених випадків використання та пояснюють, чому поведінка може відрізнятися в Excel з динамічним масивом (Microsoft 365 і Excel 2021) і традиційному Excel (2019 і старіших версій).

    Примітка: наші приклади написані для дуже простих наборів даних. Ми не можемо гарантувати, що вони будуть бездоганно працювати у ваших реальних таблицях. Ті, хто має досвід роботи з regex, погодяться, що написання регулярних виразів - це нескінченний шлях до досконалості - майже завжди є спосіб зробити його більш елегантним або здатним обробляти ширший діапазон вхідних даних.

    Регекс для вилучення числа з рядка

    Дотримуючись основної максими навчання "від простого до складного", ми почнемо з дуже простого випадку: вилучення числа з рядка.

    Перше, що вам потрібно вирішити - який номер шукати: перший, останній, конкретне входження або всі номери.

    Витягнути перше число

    Це настільки просто, наскільки може бути regex. Враховуючи, що \d означає будь-яку цифру від 0 до 9, а + означає один або кілька разів, наш регулярний вираз має такий вигляд:

    Візерунок : \d+

    Набір instance_num до 1 і ви отримаєте бажаний результат:

    =RegExpExtract(A5, "\d+", 1)

    Де A5 - вихідний рядок.

    Для зручності можна ввести шаблон в заздалегідь визначену комірку ($A$2 ) і зафіксувати її адресу знаком $:

    =RegExpExtract(A5, $A$2, 1)

    Отримати останній номер

    Щоб витягти останнє число у рядку, слід скористатися наступним шаблоном:

    Візерунок : (\d+)(?!.*\d)

    У перекладі на людську мову це звучить так: знайти число, за яким не слідує (ніде, а не тільки відразу) ніяка інша цифра. Для вираження цього ми використовуємо заперечний знак (?!.*\d), який означає, що праворуч від шаблону не повинно бути ніякої іншої цифри (\d) незалежно від того, скільки інших символів стоїть перед нею.

    =RegExpExtract(A5, "(\d+)(?!.*\d)")

    Чайові:

    • Щоб отримати конкретний випадок використовуйте \d+ для зразок та відповідний серійний номер для instance_num .
    • Формула для отримання екстракту всі номери розглядається на наступному прикладі.

    Регекс для вилучення всіх збігів

    Продовжуючи наш приклад, припустимо, що Ви хочете отримати всі числа з рядка, а не тільки одне.

    Як ви пам'ятаєте, кількість видобутих сірників контролюється опцією instance_num За замовчуванням - всі збіги, тому ви просто опускаєте цей параметр:

    =RegExpExtract(A2, "\d+")

    Формула чудово працює для однієї комірки, але поведінка відрізняється в динамічному масиві Excel та нединамічному варіанті.

    Excel 365 та Excel 2021

    Завдяки підтримці динамічних масивів звичайна формула автоматично розливається на стільки клітинок, скільки потрібно для відображення всіх розрахованих результатів. У термінах Excel це називається розлитим діапазоном:

    Excel 2019 і нижче

    У додинамічному Excel наведена вище формула повернула б лише один збіг. Щоб отримати кілька збігів, потрібно зробити її формулою масиву. Для цього виділіть діапазон клітинок, введіть формулу і натисніть Ctrl + Shift + Enter для її завершення.

    Недоліком такого підходу є купа помилок #N/A, що з'являються в "зайвих комірках". На жаль, з цим нічого не поробиш (ні IFERROR, ні IFNA, на жаль, не можуть це виправити).

    Витягнути всі збіги в одній комірці

    При обробці стовпця даних описаний вище підхід, очевидно, не спрацює. У цьому випадку ідеальним рішенням буде повернення всіх збігів в одній комірці. Для цього подайте результати RegExpExtract у функцію TEXTJOIN і розділіть їх будь-яким зручним для вас роздільником, наприклад, комою і пробілом:

    =TEXTJOIN(", ", TRUE, RegExpExtract(A5, "\d+"))

    Примітка: оскільки функція TEXTJOIN доступна тільки в Excel для Microsoft 365, Excel 2021 і Excel 2019, формула не працюватиме в старіших версіях.

    Регекс для вилучення тексту з рядка

    Витяг тексту з алфавітно-цифрового рядка є досить складним завданням в Excel. З регексом це стає простіше простого. Просто використовуйте заперечний клас, щоб зіставити все, що не є цифрою.

    Візерунок : [^\d]+

    Для отримання підрядків в окремих комірках (діапазон розливу) використовується формула:

    =RegExpExtract(A5, "[^\d]+")

    Щоб вивести всі збіги в одну комірку, вкладіть функцію RegExpExtract в TEXTJOIN таким чином:

    =TEXTJOIN("", TRUE, RegExpExtract(A5, "[^\d]+"))

    Регекс для вилучення адреси електронної пошти з рядка

    Щоб витягти адресу електронної пошти з рядка, що містить багато різної інформації, напишіть регулярний вираз, який повторює структуру адреси електронної пошти.

    Візерунок : [\w\.\-]+@[A-Za-z0-9\.\-]+\.[A-Za-z]{2,24}

    Розбиваючи цей регекс, ось що ми отримуємо:

    • [\w\.\-]+ - ім'я користувача, яке може містити 1 або більше буквено-цифрових символів, символів підкреслення, крапок та дефісів.
    • символ @
    • [A-Za-z0-9\.\-]+ - доменне ім'я, що складається з: великих і малих літер, цифр, дефісів і крапок (у разі піддоменів). Тут не допускається використання символів підкреслення, тому замість \w, що відповідає будь-якій букві, цифрі або символу підкреслення, використовуються 3 різних набори символів (наприклад, A-Z a-z і 0-9).
    • \.[A-Za-z]{2,24} - домен верхнього рівня. Складається з крапки, за якою йдуть великі та малі літери. Більшість доменів верхнього рівня мають довжину 3 літери (наприклад, .com, .org, .edu і т.д.), але теоретично він може містити від 2 до 24 літер (найдовший зареєстрований TLD).

    Якщо припустити, що рядок має формат А5, а шаблон - А2, то формула для вилучення адреси електронної пошти буде такою:

    =RegExpExtract(A5, $A$2)

    Реджекс для вилучення домену з пошти

    Коли справа доходить до вилучення поштового домену, перша думка, яка приходить в голову, - це використання групи захоплення для пошуку тексту, який безпосередньо слідує за символом @.

    Візерунок : @([A-Za-z0-9\.\-]+\.[A-Za-z]{2,24})

    Надішліть його до нашої функції RegExp:

    =RegExpExtract(A5, "@([A-Za-z0-9\.\-]+\.[A-Za-z]{2,24})")

    І ви отримаєте цей результат:

    У класичних регулярних виразах все, що знаходиться за межами групи захоплення, не включається в витяг. Чому VBA RegEx працює по-іншому і захоплює ще й "@", ніхто не знає. Щоб позбутися від нього, можна видалити перший символ з результату, замінивши його на порожній рядок.

    =REPLACE(RegExpExtract(A5, "@([a-z\d][a-z\d\-\.]*\.[a-z]{2,})", 1, FALSE), 1, 1, "")

    Регулярний вираз для вилучення телефонних номерів

    Телефонні номери можуть бути записані різними способами, тому практично неможливо придумати рішення, яке працювало б за будь-яких обставин. Тим не менш, ви можете записати всі формати, які використовуються у вашому наборі даних, і спробувати зіставити їх.

    Для цього прикладу ми створимо регекс, який буде витягувати телефонні номери в будь-якому з цих форматів:

    (123) 345-6789

    (123) 345 6789

    (123)3456789

    123-345-6789

    123.345.6789

    123 345 6789

    1233456789

    Візерунок : \(?\d{3}[-\. \)]*\d{3}[-\. ]\d{4}\b

    • Перша частина \(?\d{3} відповідає нулю або одній відкриваючій дужці, за якою слідують три цифри d{3}.
    • Частина [-\. \)]* означає будь-який символ у квадратних дужках, що зустрічається 0 або більше разів: дефіс, крапка, пробіл або закриваюча дужка.
    • Далі знову три цифри d{3}, за якими йде будь-який дефіс, крапка або пробіл [-\. ]?, що з'являється 0 або 1 раз.
    • Після цього йде група з чотирьох цифр \d{4}.
    • Нарешті, є слово boundary \b, яке визначає, що номер телефону, який ми шукаємо, не може бути частиною більшого номера.

    Повна формула має такий вигляд:

    =RegExpExtract(A5, "\(?\d{3}[-\. \)]*\d{3}[-\. ]?\d{4}\b")

    Зверніть увагу, що наведений вище регекс може повертати кілька хибнопозитивних результатів, таких як 123) 456 7899 або (123 456 7899. У наведеній нижче версії ці проблеми виправлені. Однак цей синтаксис працює тільки в функціях VBA RegExp, а не в класичних регулярних виразах.

    Візерунок : (\(\d{3}\)

    Реґекс для вилучення дати з рядка

    Регулярний вираз для вилучення дати залежить від формату, в якому дата зустрічається в рядку. Наприклад:

    Для вилучення таких дат, як 1/1/21 або 01/01/2021, регекс має вигляд: \d{1,2}\/\d{1,2}\/(\d{4})

    Він шукає групу з 1 або 2 цифр d{1,2}, за якою йде скісна риска, за якою йде інша група з 1 або 2 цифр, за якою йде скісна риска, за якою йде група з 4 або 2 цифр (\d{4})перша умова в конструкції чергування АБО виконується, решта умов не перевіряється.

    Для отримання таких дат, як 1-січня-21 або 01-січня-2021, шаблон має такий вигляд: \d{1,2}-[A-Za-z]{3}-\d{2,4}

    Він шукає групу з 1 або 2 цифр, потім дефіс, потім групу з 3 великих або малих літер, потім дефіс, потім групу з 4 або 2 цифр.

    Об'єднавши два шаблони разом, ми отримаємо наступний регекс:

    Візерунок : \b\d{1,2}[\/-](\d{1,2}

    Де:

    • Перша частина - 1 або 2 цифри: \d{1,2}.
    • Друга частина - це або 1 чи 2 цифри, або 3 літери: (\d{1,2}
    • Третя частина - група з 4 або 2 цифр: (\d{4})
    • Роздільник - пряма похила риска або дефіс: [\/-].
    • З обох боків розміщується межа слова \b, щоб було зрозуміло, що дата є окремим словом, а не частиною більшого рядка.

    Як ви можете бачити на зображенні нижче, він успішно витягує дати і пропускає підрядки, такі як 11/22/333. Однак він все одно видає помилкові спрацьовування. У нашому випадку підрядок 11-ABC-2222 в форматі A9 технічно відповідає формату дати dd-mmm-yyyy і тому видобувається.

    Для виключення помилкових спрацьовувань можна замінити частину [A-Za-z]{3} на повний список 3-буквених абревіатур місяців:

    Візерунок : \b\d{1,2}[\/-](\d{1,2}

    Щоб ігнорувати регістр літер, останній аргумент нашої користувацької функції встановлюємо в значення FALSE:

    =RegExpExtract(A5, $A$2, 1, FALSE)

    І цього разу ми отримали чудовий результат:

    Реґекс для вилучення часу з рядка

    Для того, щоб отримати час в hh:mm або hh:mm:ss наступний вираз буде дуже доречним.

    Візерунок : \b(0?[0-9]

    Розбивши цей регекс, можна побачити 2 частини, розділені символом

    Вираз 1 : \b(0?[0-9]

    Отримує час з AM/PM.

    Година може бути будь-яким числом від 0 до 12. Для його отримання використовується конструкція АБО ([0-9]

    • [0-9] відповідає будь-якому числу від 0 до 9
    • 1[0-2] відповідає будь-якому числу від 10 до 12

    Хвилина [0-5]\d - будь-яке число від 00 до 59.

    Другий (:[0-5]\d)? також може бути будь-яким числом від 00 до 59. Квантор ? означає нульове або одиничне входження, оскільки секунди можуть бути включені або не включені у значення часу.

    Вираз 2 : \b([0-9]

    Час вилучення без АМ/ПМ.

    На сьогоднішній день, на жаль, це не так. година частина може бути будь-яким числом від 0 до 32. Для її отримання використовується інша конструкція АБО ([0-9]

    • [0-9] відповідає будь-якому числу від 0 до 9
    • [0-1]\d відповідає будь-якому числу від 00 до 19
    • 2[0-3] відповідає будь-якому числу від 20 до 23

    На сьогоднішній день, на жаль, це не так. хвилина і другий частини такі ж, як у виразі 1 вище.

    Негативне випередження (?!:) додається до пропускних рядків, таких як 20:30:80.

    Оскільки PM/AM може бути як у верхньому, так і в нижньому регістрі, ми зробили функцію нечутливою до регістру:

    =RegExpExtract(A5, $A$2, 1, FALSE)

    Сподіваюся, наведені вище приклади дали вам уявлення про те, як використовувати регулярні вирази в таблицях Excel. На жаль, не всі можливості класичних регулярних виразів підтримуються в VBA. Якщо ваша задача не може бути вирішена за допомогою VBA RegExp, я рекомендую вам прочитати наступну частину, в якій розглядаються набагато більш потужні функції .NET Regex.

    Користувацька Regex-функція на основі .NET для вилучення тексту в Excel

    На відміну від функцій VBA RegExp, які може написати будь-який користувач Excel, .NET RegEx - це сфера розробника. Microsoft .NET Framework підтримує повнофункціональний синтаксис регулярних виразів, сумісний з Perl 5. Ця стаття не навчить вас писати такі функції (я не програміст і не маю ні найменшого уявлення про те, як це робиться :)

    Чотири потужні функції, що обробляються стандартним движком .NET RegEx, вже написані нашими розробниками і включені в Ultimate Suite. Нижче ми продемонструємо кілька прикладів практичного використання функції, спеціально розробленої для вилучення тексту в Excel.

    Порада. Для отримання інформації про синтаксис .NET Regex зверніться до статті Мова регулярних виразів .NET.

    Як витягти жала в Excel за допомогою регулярних виразів

    За умови, що у вас встановлена остання версія Ultimate Suite, витяг тексту за допомогою регулярних виразів зводиться до цих двох кроків:

    1. Про це йдеться на Дані про абіти у вкладці Текст групу, натисніть Regex Tools .
    2. Про це йдеться на Regex Tools виберіть вихідні дані, введіть шаблон Regex і натисніть кнопку Витяг Щоб отримати результат у вигляді користувацької функції, а не значення, виберіть опцію Вставити як формулу Після цього натисніть кнопку Витяг кнопку.

    Результати з'являться в новій колонці праворуч від Ваших вихідних даних:

    Синтаксис синтаксису RegexExtract

    Наша користувацька функція має наступний синтаксис:

    AblebitsRegexExtract(посилання, регулярний_вираз)

    Де:

    • Посилання (обов'язково) - посилання на комірку, що містить вихідний рядок.
    • Регулярний_вираз (обов'язково) - шаблон регексу для пошуку.

    Важливо: функція працює тільки на комп'ютерах з встановленим пакетом Ultimate Suite for Excel.

    Вказівки по використанню

    Для того, щоб зробити процес навчання більш плавним, а ваш досвід більш приємним, будь ласка, зверніть увагу на ці моменти:

    1. Для створення формули ви можете скористатися нашим Regex Tools або Excel Функція вставки або введіть повне ім'я функції в клітинку. Після вставки формули нею можна керувати (редагувати, копіювати або переміщувати), як будь-якою іншою власною формулою.
    2. Шаблон, який ви вводите на Regex Tools Також можна зберігати регулярний вираз в окремій комірці. У цьому випадку просто використовуйте посилання на комірку для 2-го аргументу.
    3. Функція витягує перший знайдений збіг .
    4. За замовчуванням функція з урахуванням особливостей конкретного випадку Для нечутливого до регістру збігу використовуйте шаблон (?i).
    5. Якщо збіг не знайдено, повертається помилка #N/A.

    Регекс для вилучення рядка між двома символами

    Для отримання тексту між двома символами можна використовувати або групу захоплення, або обведення.

    Припустимо, ви хочете витягти текст між дужками. Група захоплення - найпростіший спосіб.

    Шаблон 1 : \[(.*?)\]

    При позитивному погляді назад і вперед результат буде абсолютно однаковим.

    Шаблон 2 : (?<=\[)(.*?)(?=\])

    Просимо звернути увагу, що наша група захоплення (.*?) виконує лінивий пошук для тексту між двома дужками - від першої [ до першої ]. Група захоплення без знаку питання (.*) зробить так жадібний пошук і захопити все від першого [до останнього].

    З візерунком у форматі А2 формула виглядає наступним чином:

    =AblebitsRegexExtract(A5, $A$2)

    Як отримати всі матчі

    Як вже було сказано, функція AblebitsRegexExtract може витягти тільки один збіг. Щоб отримати всі збіги, можна скористатися функцією VBA, яку ми розглядали раніше. Однак є один нюанс - VBA RegExp не підтримує захоплення груп, тому наведений вище шаблон поверне ще й "граничні" символи, в нашому випадку - дужки.

    =TEXTJOIN(" ", TRUE, RegExpExtract(A5, $A$2))

    Щоб позбутися дужок, ЗАМІНИТЕ їх порожніми рядками (""), використовуючи цю формулу:

    =SUBSTITUTE(SUBSTITUTE(TEXTJOIN(", ", TRUE, RegExpExtract(A5, $A$2)), "]", ""), "[", "")

    Для кращої читабельності ми використовуємо кому для розмежування.

    Регекс для вилучення тексту між двома рядками

    Підхід, який ми розробили для вилучення тексту між двома символами, буде працювати і для вилучення тексту між двома рядками.

    Наприклад, щоб отримати все, що знаходиться між "тест 1" і "тест 2", використовуйте наступний регулярний вираз.

    Візерунок тест 1(.*?)тест 2

    Повна формула така:

    =AblebitsRegexExtract(A5, "test 1(.*?)test 2")

    Реджекс для вилучення домену з URL-адреси

    Навіть за допомогою регулярних виразів витяг доменних імен з URL-адрес не є тривіальним завданням. Ключовим елементом, який робить трюк, є незахоплення груп. Залежно від вашої кінцевої мети, виберіть один з наведених нижче регексом.

    Щоб отримати повне доменне ім'я включаючи піддомени

    Візерунок : (?:https?\:

    Щоб отримати другий рівень домен без піддоменів

    Візерунок : (?:https?\:

    Тепер давайте подивимося, як працюють ці регулярні вирази на прикладі "//www.mobile.ablebits.com" як зразка URL-адреси:

    • (?:https?\:
    • \/\/ - дві прямі похилі риски (кожній з них передує зворотна похила риска, щоб уникнути особливого значення прямої похилої риски і тлумачити її буквально).
    • (?:[A-Za-z\d\-\.]{2,255}\.)? - група, що не захоплює, для ідентифікації доменів третього, четвертого і т.д. рівня, якщо такі є ( мобільний У першому шаблоні він розміщується в більшій групі захоплення, щоб всі такі субдомени були включені в екстракцію. Субдомен може мати довжину від 2 до 255 символів, звідси і квантор {2,255}.
    • ([A-Za-z\d\-]{1,63}\.[A-Za-z]{2,24}) - група захоплення для вилучення домену другого рівня ( аандбіти ) та домен верхнього рівня ( com Максимальна довжина домену другого рівня становить 63 символи. Найдовший з існуючих на сьогоднішній день доменів верхнього рівня містить 24 символи.

    Залежно від того, який регулярний вираз введено в А2, наведена нижче формула буде давати різні результати:

    =AblebitsRegexExtract(A5, $A$2)

    Regex для вилучення повне доменне ім'я з усіма піддоменами:

    Regex для вилучення другий рівень домен без піддоменів:

    Ось так можна витягувати частини тексту в Excel за допомогою регулярних виразів. Дякую за прочитання і чекаю вас на нашому блозі наступного тижня!

    Доступні для завантаження

    Приклади Excel Regex Extract (файл .xlsm)

    Пробна версія Ultimate Suite (файл .exe)

    Майкл Браун — відданий ентузіаст технологій із пристрастю до спрощення складних процесів за допомогою програмних засобів. Маючи понад десятирічний досвід роботи в технологічній індустрії, він відточив свої навички роботи з Microsoft Excel і Outlook, а також із Google Таблицями та Документами. Блог Майкла присвячений тому, щоб поділитися своїми знаннями та досвідом з іншими, надаючи прості поради та навчальні посібники для підвищення продуктивності та ефективності. Незалежно від того, чи є ви досвідченим професіоналом чи початківцем, блог Майкла пропонує цінну інформацію та практичні поради щодо отримання максимальної користі від цих основних програмних інструментів.