Оглавление
В этом руководстве мы подробно рассмотрим, как использовать regex для сопоставления строк в Excel.
Когда вам нужно найти определенное значение в диапазоне ячеек, вы используете функцию MATCH или XMATCH. При поиске определенной строки в ячейке пригодятся функции FIND и SEARCH. А как узнать, содержит ли ячейка информацию, соответствующую заданному шаблону? Очевидно, с помощью регулярных выражений. Но Excel не поддерживает регулярные выражения! Не волнуйтесь, мы заставим его это сделать :).
Функция Regex в 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 ErrHandlRegExpMatch = 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 ErrHandl: RegExpMatch = CVErr(xlErrValue) End FunctionВставьте код в редактор VBA, и ваш новый RegExpMatch Функция готова к использованию. Если вы не очень опытны в работе с VBA, вам может быть полезно это руководство: Как вставить код VBA в Excel.
Примечание. После вставки кода не забудьте сохранить ваш файл как рабочая книга с поддержкой макросов (.xlsm).
Синтаксис RegExpMatch
Сайт RegExpMatch Функция проверяет, соответствует ли какая-либо часть исходной строки регулярному выражению. Результатом является булево значение: TRUE, если найдено хотя бы одно совпадение, FALSE в противном случае.
Наша пользовательская функция имеет 3 аргумента - первые два являются обязательными, а последний - необязательным:
RegExpMatch(text, pattern, [match_case])Где:
- Текст (обязательно) - одна или несколько строк для поиска. Может быть представлена как ссылка на ячейку или диапазон.
- Узор (требуется) - регулярное выражение для сопоставления. При помещении непосредственно в формулу шаблон должен быть заключен в двойные кавычки.
- Соответствие_случаю (необязательно) - определяет тип соответствия. Если TRUE или опущено (по умолчанию), выполняется соответствие с учетом регистра; если FALSE - без учета регистра.
Функция работает во всех версиях Excel 365, Excel 2021, Excel 2019, Excel 2016, Excel 2013 и Excel 2010.
3 вещи, которые вы должны знать о RegExpMatch
Прежде чем мы перейдем к практическим расчетам, обратите внимание на следующие моменты, которые проясняют некоторые технические моменты:
- Функция может обрабатывать отдельная клетка или диапазон ячеек В последнем случае результаты возвращаются в соседние ячейки в виде динамического массива или диапазона разлива, как показано в этом примере.
- По умолчанию функция с учетом регистра Чтобы игнорировать регистр текста, установите соответствие_случаю из-за ограничений VBA Regexp, шаблон без учета регистра (?i) не поддерживается.
- Если правильный шаблон не найден, функция возвращает FALSE; если шаблон недействителен возникает ошибка #VALUE!
Ниже вы найдете несколько примеров regex-сопоставлений, созданных в демонстрационных целях. Мы не можем гарантировать, что наши шаблоны будут безупречно работать с более широким диапазоном входных данных в ваших реальных рабочих листах. Перед запуском в производство обязательно протестируйте и настройте наши примеры шаблонов в соответствии с вашими потребностями.
Как использовать 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.
Regex для соответствия числу
Чтобы сопоставить любую цифру от 0 до 9, используйте \d В зависимости от конкретной задачи, добавьте подходящий квантификатор или создайте более сложный шаблон.
Regex для соответствия любому числу
Чтобы найти любое число любой длины, поставьте квантификатор + сразу после символа /d, который говорит, что нужно искать числа, содержащие 1 или более цифр.
Узор : \d+
=RegExpMatch(A5:A9, "\d+")
Regex для соответствия числу определенной длины
Если ваша цель - подобрать числовые значения, содержащие определенное количество цифр, то используйте \d вместе с соответствующим квантификатором.
Например, для соответствия номерам счетов, состоящим ровно из 7 цифр, вы используете \d{7}. Однако имейте в виду, что он будет соответствовать 7 цифрам в любом месте строки, включая 10-значное или 100-значное число. Если это не то, что вы ищете, поставьте слово граница \b с обеих сторон.
Узор : \b\d{7}\b
=RegExpMatch(A5:A9, "\b\d{7}\b")
Regex для сопоставления телефонных номеров
Поскольку телефонные номера могут быть записаны в различных форматах, для их сопоставления требуется более сложное регулярное выражение.
В приведенном ниже наборе данных мы будем искать 10-значные числа, которые содержат 3 цифры в первых двух группах и 4 цифры в последней группе. Группы могут быть разделены точкой, дефисом или пробелом. Первая группа может быть заключена или не заключена в круглые скобки.
Узор: (\(\d{3}\)
Разбирая это регулярное выражение, вот что мы получаем:
- Первая часть (\(\d{3}\)
- Часть [-\.\s]? означает 0 или 1 вхождение любого символа в квадратных скобках: дефиса, точки или пробела.
- Далее, есть еще одна группа из 3 цифр d{3}, за которой следует любой дефис, точка или пробел [\-\.\s], появляющийся 0 или 1 раз.
- За последней группой из 4 цифр \d{4} следует словесная граница \b, чтобы было понятно, что телефонный номер не может быть частью большего числа.
С исходной строкой в A5 и регулярным выражением в A2, формула принимает следующий вид:
=RegExpMatch(A5, $A$2)
... и работает именно так, как ожидалось:
Примечания:
- Международные коды не проверяются, поэтому они могут присутствовать или отсутствовать.
- В регулярных выражениях \s означает любой символ пробела, такой как пробел, табуляция, возврат каретки или новая строка. Чтобы разрешить только пробелы, используйте [-\. ] вместо [-\.\s].
- [^13] будет соответствовать любому символу, который не является 1 или 3.
- [^1-3] будет соответствовать любому символу, который не является 1, 2 или 3 (т.е. любой цифре от 1 до 3).
- Вышеприведенный регекс работает только для однострочный В случае многострочных строк символы ^ и $ соответствуют началу и концу каждой строки, а не началу и концу входной строки, поэтому регекс ищет только в первой строке.
- Чтобы подобрать строки, которые не начинать с определенным текстом используйте регулярное выражение, например, ^(?!лимоны).*$.
- Чтобы подобрать строки, которые не заканчиваться с определенным текстом , включите якорь конечной строки в шаблон поиска: ^((?!lemons$).)*$
- Имя пользователя может включать буквы, цифры, подчеркивания, точки и дефисы. Учитывая, что \w соответствует любой букве, цифре или подчеркиванию, мы получаем следующий регекс: [\w\.\-]+
- Доменное имя может включать прописные и строчные буквы, цифры, дефисы (но не в первой или последней позиции) и точки (в случае поддоменов). Поскольку подчеркивание не допускается, вместо \w мы используем 3 различных набора символов: [A-Za-z0-9]+[A-Za-z0-9\.\-]*[A-Za-z0-9]+
- Домен верхнего уровня состоит из точки, за которой следуют заглавные и строчные буквы. Он может содержать от 2 до 24 букв (самый длинный ДВУ, существующий в настоящее время): \.[A-Za-z]{2,24}
- Передайте RegExpMatch ссылку на диапазон, чтобы он вернул массив значений TRUE и FALSE.
- Используйте двойное отрицание (--) для приведения логических значений к единицам и нулям.
- Используйте функцию SUM для сложения 1 и 0 в полученном массиве.
- На Ablebits Data во вкладке Текст группу, нажмите Инструменты регекса .
- На Инструменты регекса панели, выполните следующие действия:
- Выберите исходные строки.
- Введите свой узор.
- Выберите Матч вариант.
- Чтобы получить результаты в виде формул, а не значений, выберите параметр Вставка в виде формулы флажок.
- Нажмите кнопку Матч кнопка.
- Функция может быть вставлено непосредственно в камере через стандарт Функция вставки диалоговое окно, где он находится в категории AblebitsUDFs .
- По умолчанию регулярное выражение добавляется в формулу, но вы также можете хранить его в отдельной ячейке. Для этого просто используйте ссылку на ячейку для 2-го аргумента.
- По умолчанию функция с учетом регистра Для сопоставления без учета регистра используйте шаблон (?i).
Regex для НЕ совпадения символов
Чтобы найти строки, которые НЕ содержат определенного символа, можно использовать классы отрицаемых символов [^ ], которые соответствуют всему, что НЕ заключено в скобки. Например:
В списке телефонных номеров, предположим, вы хотите найти те, которые не имеют кода страны. Помня, что любой международный код включает знак +, вы можете использовать класс символов [^\+], чтобы найти строки, которые не содержат знак плюс. Важно понимать, что приведенное выше выражение соответствует любому символу, который не является +. Поскольку телефонный номер может находиться в любом месте строки, необязательно в самом начале, квантификатор * добавляется для проверки каждого последующего символа. начальный ^ и конечный $ якоря обеспечивают обработку всей строки. в результате мы получаем следующее регулярное выражение, которое гласит "не сопоставлять символ + в любой позиции строки".
Узор : ^[^\+]*$
=RegExpMatch(A5, "^[^\+]*$")
Regex для НЕ соответствия строки
Хотя не существует специального синтаксиса регулярного выражения для несоответствия конкретной строке, вы можете имитировать такое поведение, используя отрицательную задержку.
Предположим, вы хотите найти строки, которые не содержат слово "лимоны". Это регулярное выражение будет работать отлично:
Узор : ^(((?!лимоны).)*$
Очевидно, что здесь необходимо пояснение. Отрицательное опережение (?!lemons) смотрит вправо, нет ли впереди слова "lemons". Если "lemons" там нет, то точка соответствует любому символу, кроме перевода строки. Приведенное выше выражение выполняет только одну проверку, а квантификатор * повторяет ее ноль или более раз, от начала строки, закрепленной ^, до конца строки, закрепленной$.
Чтобы игнорировать регистр текста, мы устанавливаем 3-й аргумент в FALSE, чтобы сделать нашу функцию нечувствительной к регистру:
=RegExpMatch(A5, $A$2, FALSE)
Советы и примечания:
Сопоставление без учета регистра
В классических регулярных выражениях существует специальный шаблон для сопоставления без учета регистра (?i), который не поддерживается в VBA RegExp. Чтобы преодолеть это ограничение, наша пользовательская функция принимает 3-й необязательный аргумент с именем соответствие_случаю Для того, чтобы выполнить поиск без учета регистра, просто установите значение FALSE.
Допустим, вы хотите определить такие даты, как 1-мар-22 или 01-мар-2022 г. Чтобы сопоставить dd-mmm-yyy и d-mmm-yy форматов, мы используем следующее регулярное выражение.
Узор : \b\d{1,2}-(Jan
Наше выражение ищет группу из 1 или 2 цифр, за которыми следует дефис, а затем любую из аббревиатур месяца, разделенных символом
Почему бы не использовать более простой шаблон, например, \d{1,2}-[A-Za-z]{3}-\d{2,4}\b? Чтобы избежать ложных срабатываний, например, 01-ABC-2020.
Введите шаблон в A2, и вы получите следующую формулу:
=RegExpMatch(A5, $A$2, FALSE)
Regex для соответствия действительным адресам электронной почты
Как известно, адрес электронной почты состоит из 4 частей: имя пользователя, символ @, доменное имя (почтовый сервер) и домен верхнего уровня (например, .com, .edu, .org и т.д.). Чтобы проверить достоверность адреса электронной почты, нам нужно воспроизвести приведенную выше структуру с помощью регулярных выражений.
Узор : \b[\w\.\-]+@[A-Za-z0-9]+[A-Za-z0-9\.\-]*[A-Za-z0-9]+\.[A-Za-z]{2,24}\b
Чтобы лучше понять, что здесь происходит, давайте рассмотрим каждую часть подробнее:
Примечание. В шаблоне предполагается, что имя домена содержит 2 или более буквенно-цифровых символа.
Если исходный текст находится в формате A5, а шаблон - в формате A5, формула принимает такой вид:
=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 с совпадающим регексом
Поскольку встроенные и пользовательские функции прекрасно сочетаются друг с другом, ничто не мешает вам использовать их вместе в одной формуле.
Чтобы вернуть или вычислить что-то, если регулярное выражение совпало, и что-то другое, если оно не совпало, встройте пользовательскую функцию RegExpMatch в логический текст IF:
IF(RegExpMatch(...), [value_if_true], [value_if_false])Например, если строка в A5 содержит действительный адрес электронной почты, вы можете вернуть "Да"; в противном случае "Нет".
=IF(RegExpMatch(A5, $A$2,), "Да", "Нет")
Подсчитывает, совпал ли регекс
Поскольку собственные функции Excel не поддерживают регулярные выражения, невозможно поместить regex непосредственно в функцию COUNTIS или COUNTIFS. К счастью, вы можете эмулировать эту функциональность с помощью нашей пользовательской функции.
Предположим, вы использовали regex для сопоставления телефонных номеров и вывели результаты в столбец B. Чтобы узнать, сколько ячеек содержат телефонные номера, вам нужно просто подсчитать значения TRUE в B5:B9. И это можно легко сделать с помощью стандартной формулы COUNTIF:
=COUNTIF(B5:B9, TRUE)
Не хотите лишних столбцов в рабочем листе? Нет проблем. Помня о том, что наша пользовательская функция может обрабатывать несколько ячеек одновременно, а SUM в Excel может суммировать значения в массиве, вот что вы сделаете:
=SUM(--RegExpMatch(A5:A9, $A$2))
Regex-сопоставление с помощью Ultimate Suite
Пользователи нашего пакета Ultimate Suite могут использовать четыре мощные функции Regex без добавления кода VBA в свои рабочие книги, поскольку они плавно интегрируются в Excel во время установки надстройки. Наши пользовательские функции обрабатываются стандартным механизмом .NET RegEx и поддерживают полнофункциональные классические регулярные выражения.
Как использовать пользовательскую функцию RegexMatch
Если у вас установлена последняя версия Ultimate Suite (2021.4 или более поздняя), вы можете создать формулу Regex Match в два простых шага:
Мгновение спустя AblebitsRegexMatch функция вставляется в новый столбец справа от ваших данных.
На скриншоте ниже функция проверяет, содержат ли строки в столбце A 7-значные числа или нет.
Советы:
Для получения дополнительной информации смотрите функцию AblebitsRegexMatch.
Вот как выполнять сопоставление регулярных выражений в Excel. Я благодарю вас за прочтение и с нетерпением жду встречи с вами в нашем блоге на следующей неделе!
Доступные загрузки
Примеры Excel Regex Match (файл.xlsm)
Ultimate Suite 14-дневная полнофункциональная версия (файл .exe)