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

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

У цьому уроці ми детально розглянемо, як використовувати regex для зіставлення рядків в Excel.

Коли вам потрібно знайти певне значення в діапазоні комірок, ви скористаєтеся функцією СООТВЕТСТВИЕ або ХСООТВЕТСТВИЕ. Для пошуку конкретного рядка в комірці стануть в нагоді функції НАЙТИ і ПОИСК. А як дізнатися, чи містить комірка інформацію, яка відповідає заданому шаблону? Очевидно, за допомогою регулярних виразів. Але "з коробки" Excel не підтримує регулярні вирази! Не хвилюйтеся, ми змусимо його це зробити :)

    Регекс-функція Excel VBA для зіставлення рядків

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

    Public Function RegExpMatch(input_range As Range, pattern As String , Optional match_case As Boolean = True ) As Variant Dim arRes() As Variant 'масив для зберігання результатів Dim iInputCurRow, iInputCurCol, cntInputRows, cntInputCols As Long 'індекс поточного рядка у вихідному діапазоні, індекс поточного стовпця у вихідному діапазоні, кількість рядків, кількість стовпчиків On Error GoTo ErrHandleRegExpMatch = arRes Set regex = CreateObject ( "VBScript.RegExp" ) regex.pattern = pattern regex.Global = True regex.MultiLine = True If True = match_case Then regex.ignorecase = False Else regex.ignorecase = True End If cntInputRows = input_range.Rows.Count cntInputCols = input_range.Columns.Count ReDim arRes(1 To cntInputRows, 1 To cntInputCols) For iInputCurRow = 1 To cntInputRows ForiInputCurCol = 1 To cntInputCols arRes(iInputCurRow, iInputCurCol) = regex.Test(input_range.Cells(iInputCurRow, iInputCurCol).Value) Next Next RegExpMatch = arRes Exit Function ErrHandle: RegExpMatch = CVErr(xlErrValue) End Function

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

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

    Синтаксис RegExpMatch

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

    Наша користувацька функція має 3 аргументи - перші два обов'язкові, а останній необов'язковий:

    RegExpMatch(text, pattern, [match_case])

    Де:

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

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

    3 речі, які варто знати про RegExpMatch

    Перш ніж перейти до практичних розрахунків, просимо звернути увагу на наступні моменти, які роз'яснюють деякі технічні моменти:

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

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

    Як використовувати regex для зіставлення рядків в Excel

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

    Припустимо, що у Вас є діапазон комірок (A5:A9), що містять різні відомості про деякі товари. Ви хочете знати, в яких комірках є SKU. Припускаючи, що кожен SKU складається з 2 великих літер, дефісу і 3 цифр, Ви можете зіставити їх, використовуючи наступний вираз.

    Візерунок : \b[A-Z]{2}-\d{3}\b

    Де [A-Z]{2} означає будь-які 2 великі літери від A до Z і \d{3} означає будь-які 3 цифри від 0 до 9. Символ \b позначає межу слова, тобто SKU є окремим словом, а не частиною більшого рядка, наприклад, 23-MAR-2022.

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

    Збіг рядка в одній комірці

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

    =RegExpMatch(A5, "\b[A-Z]{2}-\d{3}\b")

    Шаблон також може зберігатися в заздалегідь визначеній комірці, яка блокується абсолютним посиланням ($A$2):

    =RegExpMatch(A5, $A$2)

    Після введення формули в першу комірку можна перетягнути її вниз на всі інші рядки.

    Цей метод чудово працює в всі версії Excel .

    Збіг рядків у декількох комірках одночасно

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

    =RegExpMatch(A5:A9, "\b[A-Z]{2}-\d{3}\b")

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

    В Excel 2019 а раніше він працює тільки як традиційна формула масиву CSE, яка вводиться в діапазон комірок і завершується натисканням клавіш Ctrl + Shift + Enter разом.

    Регекс для збігу з номером

    Щоб підібрати будь-яку цифру від 0 до 9, використовуйте \d Залежно від конкретного завдання, додайте відповідний квантор або створіть більш складний шаблон.

    Регекс на відповідність будь-якому числу

    Щоб знайти число будь-якої довжини, відразу після символу /d слід поставити квантор +, який вказує шукати числа, що містять 1 або більше цифр.

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

    =RegExpMatch(A5:A9, "\d+")

    Регекс на відповідність номеру певної довжини

    Якщо ваша мета - зіставити числові значення, що містять певну кількість цифр, то використовуйте \d разом з відповідним квантифікатором.

    Наприклад, для пошуку номерів рахунків-фактур, що складаються рівно з 7 цифр, використовуйте \d{7}. Однак, будь ласка, майте на увазі, що він буде відповідати 7 цифрам в будь-якому місці рядка, включаючи 10-значне або 100-значне число. Якщо це не те, що ви шукаєте, поставте слово boundary \b з обох боків.

    Візерунок : \b\d{7}\b

    =RegExpMatch(A5:A9, "\b\d{7}\b")

    Регекс для зіставлення номерів телефонів

    Оскільки телефонні номери можуть бути записані в різних форматах, для їх зіставлення потрібен більш складний регулярний вираз.

    У наведеному нижче наборі даних ми будемо шукати 10-значні числа, які мають по 3 цифри в перших 2 групах і 4 цифри в останній групі. Групи можуть бути розділені крапкою, дефісом або пропуском. Перша група може бути взята в круглі дужки, а може і не бути.

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

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

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

    З вихідним рядком в комірці А5 та регулярним виразом в комірці А2 формула набуває такого вигляду:

    =RegExpMatch(A5, $A$2)

    ...і працює саме так, як очікувалося:

    Нотатки:

    • Міжнародні коди не перевіряються, тому вони можуть бути присутніми, а можуть і не бути.
    • У регулярних виразах \s означає будь-який пробіл, наприклад, пробіл, табуляцію, повернення каретки або новий рядок. Щоб дозволити тільки пробіли, використовуйте [-\. ] замість [-\.\s].
    • Збіг регексу з символом НЕ збігається

      Для пошуку рядків, які НЕ містять певного символу, можна використовувати заперечні класи символів [^ ], які збігаються з будь-чим НЕ в дужках. Наприклад:

      • [^13] буде відповідати будь-якому символу, який не є 1 або 3.
      • [^1-3] буде відповідати будь-якому символу, який не є 1, 2 або 3 (тобто будь-якій цифрі від 1 до 3).

      У списку телефонних номерів, припустимо, потрібно знайти ті, які не мають коду країни. Пам'ятаючи, що будь-який міжнародний код включає в себе знак +, можна використовувати клас символів [^\+] для пошуку рядків, які не містять знак плюс. Важливо розуміти, що вищенаведений вираз відповідає будь-якому окремому символу, який не є +. Оскільки номер телефону може знаходитися в будь-якому місці рядка, а необов'язково на самому початку додається квантор * для перевірки кожного наступного символу. Початковий ^ і кінцевий $ якорі забезпечують обробку всього рядка. В результаті отримуємо наведений нижче регулярний вираз, який говорить "не зустрічати символ + в будь-якій позиції рядка".

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

      =RegExpMatch(A5, "^[^\+]*$")

      Рядок, що не збігається з регексом

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

      Припустимо, ви хочете знайти рядки, які не містять слово "лимони". Цей регулярний вираз спрацює на славу:

      Візерунок : ^((?!лимони).)*$

      Очевидно, що тут потрібні деякі пояснення. Негативне застереження (?!lemons) дивиться праворуч, щоб побачити, чи немає попереду слова "lemons". Якщо "lemons" там немає, то крапка відповідає будь-якому символу, крім розриву рядка. Вищенаведений вираз виконує лише одну перевірку, а квантор * повторює її нуль або більше разів, від початку рядка, закріпленого символом ^, до кінця рядка, закріпленого символом$.

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

      =RegExpMatch(A5, $A$2, FALSE)

      Поради та примітки:

      • Вищевказаний регекс працює тільки для однолінійний У випадку мілті-рядкових рядків символи ^ та $ відповідають початку та кінцю кожного рядка, а не початку та кінцю вхідного рядка, тому регекс шукає тільки в першому рядку.
      • Щоб зіставити рядки, які не запускати з певним текстом використовуйте регулярний вираз на зразок ^(?!лимони).*$
      • Щоб зіставити рядки, які не закінчуються з певним текстом включіть в шаблон пошуку якір кінцевого рядка: ^((?!lemons$).)*$

      Нечутливе до регістру узгодження

      У класичних регулярних виразах існує спеціальний шаблон для нечутливого до регістру співпадіння (?i), який не підтримується в VBA RegExp. Щоб подолати це обмеження, наша користувацька функція приймає 3-й необов'язковий аргумент з іменем match_case Для того, щоб зробити зіставлення без урахування регістру, просто встановіть значення FALSE.

      Припустимо, ви хочете ідентифікувати такі дати, як 1-Мар-22 або 01-Мар-2022. Для того, щоб відповідати dd-mmm-yyyy і д-ммм-yy ми використовуємо наступний регулярний вираз.

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

      Наш вираз шукає групу з 1 або 2 цифр, за якими слідує дефіс, а потім будь-яка з абревіатур місяців, розділених символами

      Чому б не використати простіший шаблон, такий як \d{1,2}-[A-Za-z]{3}-\d{2,4}\b? Щоб запобігти хибнопозитивним збігам, таким як 01-ABC-2020.

      Введіть візерунок у форматі А2, і ви отримаєте наступну формулу:

      =RegExpMatch(A5, $A$2, FALSE)

      Регекс для перевірки валідних адрес електронної пошти

      Як відомо, адреса електронної пошти складається з 4-х частин: імені користувача, символу @, доменного імені (поштового сервера) та домену верхнього рівня (наприклад, .com, .edu, .org і т.д.). Для того, щоб перевірити валідність адреси електронної пошти, нам потрібно буде відтворити вищевказану структуру за допомогою регулярних виразів.

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

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

      • Ім'я користувача може включати в себе букви, цифри, підкреслення, крапки і дефіси. Враховуючи, що \w відповідає будь-якій букві, цифрі або підкресленню, отримуємо наступний реглекс: [\w\.\-]+
      • Доменне ім'я може містити великі та малі літери, цифри, дефіси (але не в першій або останній позиції) і крапки (у випадку піддоменів). Оскільки підкреслення не допускаються, замість \w ми використовуємо 3 різних набори символів: [A-Za-z0-9]+[A-Za-z0-9\.\-]*[A-Za-z0-9]+[A-Za-z0-9]+
      • Домен верхнього рівня Складається з крапки, за якою йдуть великі та малі літери. Може містити від 2 до 24 літер (найдовший з існуючих на сьогоднішній день доменів верхнього рівня): \.[A-Za-z]{2,24}

      Примітка: Шаблон передбачає, що доменне ім'я містить 2 і більше алфавітно-цифрових символів.

      З оригінальним текстом у форматі А5 та малюнком у форматі А5 формула набуває такого вигляду:

      =RegExpMatch(A5, $A$2)

      Або ви можете використовувати простіший регулярний вираз для перевірки електронної пошти з набором символів у нижньому або верхньому регістрі:

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

      Але зробіть свою формулу нечутливою до регістру:

      =RegExpMatch(A5, $A$2, FALSE)

      Формула Excel ЕСЛИ зі збігом регексу

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

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

      IF(RegExpMatch(...), [значення_якщо_істина], [значення_якщо_хибність])

      Наприклад, якщо рядок в А5 містить дійсну адресу електронної пошти, можна повернути "Так", в іншому випадку - "Ні".

      =IF(RegExpMatch(A5, $A$2,), "Так", "Ні")

      Підрахувати, чи співпав regex

      Оскільки вбудовані функції Excel не підтримують регулярні вирази, неможливо помістити регекс безпосередньо в функцію COUNTIS або COUNTIFS. На щастя, ви можете емулювати цю функціональність за допомогою нашої спеціальної функції.

      Припустимо, ви використовували регекс для зіставлення телефонних номерів і вивели результати в стовпчик B. Щоб дізнатися, скільки клітинок містять телефонні номери, вам просто потрібно підрахувати значення ІСТИНА в клітинках B5:B9. І це можна легко зробити за допомогою стандартної формули COUNTIF:

      =COUNTIF(B5:B9, TRUE)

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

      • Передайте посилання на діапазон в RegExpMatch, щоб він повернув масив значень TRUE і FALSE.
      • Використовуйте подвійне заперечення (--) для примусу логічних значень до одиниць і нулів.
      • Отримати функцію SUM для додавання одиниць та нулів у результуючому масиві.

      =SUM(--RegExpMatch(A5:A9, $A$2))

      Співставлення регексу з Ultimate Suite

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

      Як використовувати користувацьку функцію RegexMatch

      Якщо у вас встановлена остання версія Ultimate Suite (2021.4 або новіша), ви можете створити формулу Regex Match у два простих кроки:

      1. Про це йдеться на Дані про абіти у вкладці Текст групу, натисніть Regex Tools .

    • Про це йдеться на Regex Tools виконайте наступні дії:
      • Виберіть вихідні рядки.
      • Введіть свій візерунок.
      • Обирайте Матч варіант.
      • Щоб отримати результати у вигляді формул, а не значень, виберіть опцію Вставити як формулу прапорець.
      • Натисніть на кнопку Матч кнопку.

      За мить після того, як АблебітиRegexMatch вставляється в новий стовпчик праворуч від ваших даних.

      На скріншоті нижче функція перевіряє, чи містять рядки в колонці A 7-значні числа чи ні.

      Чайові:

      • Функція може бути вставлений безпосередньо в камері через стандарт Функція вставки діалогове вікно, в якому вона віднесена до категорії AblebitsUDF .
      • За замовчуванням у формулу додається регулярний вираз, але його також можна тримати в окремій комірці. Для цього достатньо використати посилання на комірку для 2-го аргументу.
      • За замовчуванням функція з урахуванням особливостей конкретного випадку Для нечутливого до регістру збігу використовуйте шаблон (?i).

      Для більш детальної інформації, будь ласка, зверніться до функції AblebitsRegexMatch.

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

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

      Приклади регексних збігів в Excel (файл .xlsm)

      Ultimate Suite 14-денна повнофункціональна версія (файл .exe)

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