Регулярные выражения в vba для excel

Регулярные выражения в VBA Excel. Объекты RegExp, Match, Matches Collection и их свойства. Символы и метасимволы. Создание объекта RegExp с ранней, поздней привязкой и его методы.

Регулярные выражения (по Википедии) – это формальный язык поиска и осуществления манипуляций с подстроками в тексте. Они используются для обработки текстов с помощью шаблонов, состоящих из символов и метасимволов, и представлены объектом RegExp.

В VBA Excel для работы с регулярными выражениями используется библиотека «Microsoft VBScript Regular Expression».

Создание объекта RegExp

Ранняя привязка

Обычно рекомендуется использовать объекты с ранней привязкой, так как у них выше быстродействие, а также при написании и редактировании кода доступны подсказки  в виде листа свойств-методов, появляющегося автоматически или вызываемого, при необходимости, сочетанием клавиш Ctrl+Пробел.

Раннее связывание заключается в присвоении нового экземпляра объекта RegExp переменной, уже объявленной, как переменная определенного типа (в нашем случае, как RegExp).

Для осуществления ранней привязки необходимо подключить к проекту VBA ссылку на библиотеку «Microsoft VBScript Regular Expression», для чего в редакторе VBA выбираем Tools — References…

Меню Tools окна Project-VBAProject

В открывшемся окне «References» находим строку «Microsoft VBScript Regular Expression 5.5» (если у вас ее нет, то строку «Microsoft VBScript Regular Expression 1.0»), отмечаем ее галочкой и нажимаем «ОК».

Окно References-VBAProject

Готово — ссылка добавлена.

Создание объекта RegExp с ранней привязкой:

‘Вариант 1

Dim myRegExp As RegExp

Set myRegExp = New RegExp

‘————————-

‘Вариант 2

Dim myRegExp As New RegExp

Поздняя привязка

Позднее связывание заключается в присвоении нового экземпляра объекта RegExp переменной, объявленной как Object, с помощью функции CreateObject.

Создание объекта RegExp с поздней привязкой:

Dim myRegExp As Object

Set myRegExp = CreateObject(«VBScript.RegExp»)

Свойства и методы объекта RegExp

Свойства объекта RegExp

Свойство Описание Значение
по умолчанию
Global Определяет продолжительность поиска:
False — до первого совпадения
True — по всему тексту
False
IgnoreCase Определяет чувствительность к регистру символов:
False — учитывать регистр
True — не учитывать регистр
False
Multiline Определяет структуру объекта:
False — однострочный
True — многострочный
False
Pattern Строка, используемая как шаблон Пустая строка

Свойства объекта RegExp доступны для чтения и записи.

Методы объекта RegExp

Метод Синтаксис Описание
Execute Execute(myStr)
myStr — строка для поиска
Возвращает коллекцию найденных по шаблону подстрок в виде агрегатного объекта
Replace Replace(myStr,myRep)
myStr — строка для поиска
myRep — строка для замены
Возвращает строку, в которой найденные по шаблону вхождения в исходной строке заменены на указанную подстроку.
Test Test(myText)
myText — строка для проверки
Возвращает булево значение как результат проверки соответствия строки шаблону

Свойства объектов Match и Matches Collection

Метод Execute объекта RegExp возвращает агрегатный объект Matches Collection, который содержит коллекцию объектов Match, представляющих все совпадения, найденные механизмом регулярных выражений, в том порядке, в котором они присутствуют в исходной строке. Если совпадений нет, метод возвращает объект Matches Collection без членов.

Свойства объекта Matches Collection

Свойство Описание
Count Количество объектов Match, содержащихся в объекте Matches Collection
Item Индекс члена коллекции от нуля до значения свойства Count минус 1

Свойства объекта Matches Collection доступны только для чтения.

Свойства объекта Match

Свойство Описание
FirstIndex Позиция в исходной строке, где произошло совпадение, причем первая позиция в строке равна нулю
Length Длина совпавшей подстроки
Value Найденная подстрока (является свойством по умолчанию)

Свойства объекта Match доступны только для чтения.

Символы и метасимволы

Все знаки, используемые для составления шаблонов, обычно делят на символы и метасимволы. Символы — это знаки, которые в шаблонах обозначают сами себя, а метасимволы (спецсимволы) — знаки, имеющие другое значение. Метасимволы могут использоваться как отдельно, так и в сочетании с другими символами и спецсимволами.
Таблица основных метасимволов и их сочетаний с другими символами

Метасимвол
(сочетание символов)
Значение
После этого знака метасимвол обозначает сам себя, а некоторые символы приобретают другое значение
^ Начало строки
$ Конец строки
? Ни одного или один любой символ
* Ни одного или несколько любых символов
+ Один или несколько любых символов
. Любой символ, кроме знака «новая строка»
Определяет интервал символов
| Знак «или»
{n} Точное количество символов, стоящих перед {n}
{n,m} Количество от n до m символов, стоящих перед {n,m}
[abc] Любой из указанных символов
[^abc] Любой из неуказанных символов
[a-z] Любой символ из диапазона
[^a-z] Любой символ, не входящий в диапазон
b Конец слова
B Не конец слова
d Цифра
D Не цифра
w Любая буква, цифра или знак подчеркивания
W Не буква, не цифра и не знак подчеркивания
s Пробел
S Не пробел

В таблицу не включены редко используемые сочетания, ознакомиться с которыми можно в справочной системе разработчика. А примеры использования метасимволов в шаблонах очень хорошо представлены на этом ресурсе в разделе 4. Метасимволы.

Пример использования RegExp

Пример использования регулярных выражений в VBA Excel для извлечения email-адресов из текстового файла.

Для извлечения текстовой информации из файла в переменную используется функция GetText, которую вы можете скопировать из статьи Парсинг сайтов, html-страниц и файлов.

В файл «Новый документ.txt» вставлен произвольный текст с четырьмя примерами email-адресов, которые необходимо извлечь.

Код VBA Excel для извлечения email-адресов из текстового файла с помощью регулярных выражений:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

Sub Primer()

Dim htmlText As String, myRegExp As Object, myObj As Object, myStr1 As Object, myStr2 As String

‘Присваиваем переменной htmlText текстовую информацию из файла «Новый документ.txt»

htmlText = GetText(«C:UsersEvgeniyDownloadsНовый документ.txt»)

‘Присваиваем переменной myRegExp ссылку на новый экземпляр RegExp

Set myRegExp = CreateObject(«VBScript.RegExp»)

    With myRegExp

        ‘Задаем поиск по всему тексту

        .Global = True

        ‘Задаем шаблон поиска

        .Pattern = «([w.-]+)@([w.-]+).([A-Za-z]{2,6})»

        ‘Присваиваем переменной myObj коллекцию найденных по шаблону email-адресов

        Set myObj = .Execute(htmlText)

    End With

    For Each myStr1 In myObj

        ‘Извлекаем email-адреса из коллекции myObj по очереди в объектную переменную myStr1

        ‘и записываем их построчно в текстовую переменную myStr2

        myStr2 = myStr2 & myStr1 & vbNewLine

    Next

‘Смотрим, что получилось

MsgBox myStr2

End Sub

У меня результат работы кода выглядел так:


Regular expressions are used for Pattern Matching.

To use in Excel follow these steps:

Step 1: Add VBA reference to «Microsoft VBScript Regular Expressions 5.5»

  • Select «Developer» tab (I don’t have this tab what do I do?)
  • Select «Visual Basic» icon from ‘Code’ ribbon section
  • In «Microsoft Visual Basic for Applications» window select «Tools» from the top menu.
  • Select «References»
  • Check the box next to «Microsoft VBScript Regular Expressions 5.5» to include in your workbook.
  • Click «OK»

Step 2: Define your pattern

Basic definitions:

- Range.

  • E.g. a-z matches an lower case letters from a to z
  • E.g. 0-5 matches any number from 0 to 5

[] Match exactly one of the objects inside these brackets.

  • E.g. [a] matches the letter a
  • E.g. [abc] matches a single letter which can be a, b or c
  • E.g. [a-z] matches any single lower case letter of the alphabet.

() Groups different matches for return purposes. See examples below.

{} Multiplier for repeated copies of pattern defined before it.

  • E.g. [a]{2} matches two consecutive lower case letter a: aa
  • E.g. [a]{1,3} matches at least one and up to three lower case letter a, aa, aaa

+ Match at least one, or more, of the pattern defined before it.

  • E.g. a+ will match consecutive a’s a, aa, aaa, and so on

? Match zero or one of the pattern defined before it.

  • E.g. Pattern may or may not be present but can only be matched one time.
  • E.g. [a-z]? matches empty string or any single lower case letter.

* Match zero or more of the pattern defined before it.

  • E.g. Wildcard for pattern that may or may not be present.
  • E.g. [a-z]* matches empty string or string of lower case letters.

. Matches any character except newline n

  • E.g. a. Matches a two character string starting with a and ending with anything except n

| OR operator

  • E.g. a|b means either a or b can be matched.
  • E.g. red|white|orange matches exactly one of the colors.

^ NOT operator

  • E.g. [^0-9] character can not contain a number
  • E.g. [^aA] character can not be lower case a or upper case A

Escapes special character that follows (overrides above behavior)

  • E.g. ., \, (, ?, $, ^

Anchoring Patterns:

^ Match must occur at start of string

  • E.g. ^a First character must be lower case letter a
  • E.g. ^[0-9] First character must be a number.

$ Match must occur at end of string

  • E.g. a$ Last character must be lower case letter a

Precedence table:

Order  Name                Representation
1      Parentheses         ( )
2      Multipliers         ? + * {m,n} {m, n}?
3      Sequence & Anchors  abc ^ $
4      Alternation         |

Predefined Character Abbreviations:

abr    same as       meaning
d     [0-9]         Any single digit
D     [^0-9]        Any single character that's not a digit
w     [a-zA-Z0-9_]  Any word character
W     [^a-zA-Z0-9_] Any non-word character
s     [ rtnf]   Any space character
S     [^ rtnf]  Any non-space character
n     [n]          New line

Example 1: Run as macro

The following example macro looks at the value in cell A1 to see if the first 1 or 2 characters are digits. If so, they are removed and the rest of the string is displayed. If not, then a box appears telling you that no match is found. Cell A1 values of 12abc will return abc, value of 1abc will return abc, value of abc123 will return «Not Matched» because the digits were not at the start of the string.

Private Sub simpleRegex()
    Dim strPattern As String: strPattern = "^[0-9]{1,2}"
    Dim strReplace As String: strReplace = ""
    Dim regEx As New RegExp
    Dim strInput As String
    Dim Myrange As Range
    
    Set Myrange = ActiveSheet.Range("A1")
    
    If strPattern <> "" Then
        strInput = Myrange.Value
        
        With regEx
            .Global = True
            .MultiLine = True
            .IgnoreCase = False
            .Pattern = strPattern
        End With
        
        If regEx.Test(strInput) Then
            MsgBox (regEx.Replace(strInput, strReplace))
        Else
            MsgBox ("Not matched")
        End If
    End If
End Sub

Example 2: Run as an in-cell function

This example is the same as example 1 but is setup to run as an in-cell function. To use, change the code to this:

Function simpleCellRegex(Myrange As Range) As String
    Dim regEx As New RegExp
    Dim strPattern As String
    Dim strInput As String
    Dim strReplace As String
    Dim strOutput As String
    
    
    strPattern = "^[0-9]{1,3}"
    
    If strPattern <> "" Then
        strInput = Myrange.Value
        strReplace = ""
        
        With regEx
            .Global = True
            .MultiLine = True
            .IgnoreCase = False
            .Pattern = strPattern
        End With
        
        If regEx.test(strInput) Then
            simpleCellRegex = regEx.Replace(strInput, strReplace)
        Else
            simpleCellRegex = "Not matched"
        End If
    End If
End Function

Place your strings («12abc») in cell A1. Enter this formula =simpleCellRegex(A1) in cell B1 and the result will be «abc».

results image


Example 3: Loop Through Range

This example is the same as example 1 but loops through a range of cells.

Private Sub simpleRegex()
    Dim strPattern As String: strPattern = "^[0-9]{1,2}"
    Dim strReplace As String: strReplace = ""
    Dim regEx As New RegExp
    Dim strInput As String
    Dim Myrange As Range
    
    Set Myrange = ActiveSheet.Range("A1:A5")
    
    For Each cell In Myrange
        If strPattern <> "" Then
            strInput = cell.Value
            
            With regEx
                .Global = True
                .MultiLine = True
                .IgnoreCase = False
                .Pattern = strPattern
            End With
            
            If regEx.Test(strInput) Then
                MsgBox (regEx.Replace(strInput, strReplace))
            Else
                MsgBox ("Not matched")
            End If
        End If
    Next
End Sub

Example 4: Splitting apart different patterns

This example loops through a range (A1, A2 & A3) and looks for a string starting with three digits followed by a single alpha character and then 4 numeric digits. The output splits apart the pattern matches into adjacent cells by using the (). $1 represents the first pattern matched within the first set of ().

Private Sub splitUpRegexPattern()
    Dim regEx As New RegExp
    Dim strPattern As String
    Dim strInput As String
    Dim Myrange As Range
    
    Set Myrange = ActiveSheet.Range("A1:A3")
    
    For Each C In Myrange
        strPattern = "(^[0-9]{3})([a-zA-Z])([0-9]{4})"
        
        If strPattern <> "" Then
            strInput = C.Value
            
            With regEx
                .Global = True
                .MultiLine = True
                .IgnoreCase = False
                .Pattern = strPattern
            End With
            
            If regEx.test(strInput) Then
                C.Offset(0, 1) = regEx.Replace(strInput, "$1")
                C.Offset(0, 2) = regEx.Replace(strInput, "$2")
                C.Offset(0, 3) = regEx.Replace(strInput, "$3")
            Else
                C.Offset(0, 1) = "(Not matched)"
            End If
        End If
    Next
End Sub

Results:

results image


Additional Pattern Examples

String   Regex Pattern                  Explanation
a1aaa    [a-zA-Z][0-9][a-zA-Z]{3}       Single alpha, single digit, three alpha characters
a1aaa    [a-zA-Z]?[0-9][a-zA-Z]{3}      May or may not have preceding alpha character
a1aaa    [a-zA-Z][0-9][a-zA-Z]{0,3}     Single alpha, single digit, 0 to 3 alpha characters
a1aaa    [a-zA-Z][0-9][a-zA-Z]*         Single alpha, single digit, followed by any number of alpha characters

</i8>    </[a-zA-Z][0-9]>            Exact non-word character except any single alpha followed by any single digit

Разбор текста регулярными выражениямиОдной из самых трудоемких и неприятных задач при работе с текстом в Excel является парсинг — разбор буквенно-цифровой «каши» на составляющие и извлечение из нее нужных нам фрагментов. Например:

  • извлечение почтового индекса из адреса (хорошо, если индекс всегда в начале, а если нет?)
  • нахождение номера и даты счета из описания платежа в банковской выписке
  • извлечение ИНН из разношерстных описаний компаний в списке контрагентов
  • поиск номера автомобиля или артикула товара в описании и т.д.

Обычно во подобных случаях, после получасового муторного ковыряния в тексте вручную, в голову начинают приходить мысли как-то автоматизировать этот процесс (особенно если данных много). Решений тут несколько и с разной степенью сложности-эффективности:

  • Использовать встроенные текстовые функции Excel для поиска-нарезки-склейки текста: ЛЕВСИМВ (LEFT), ПРАВСИМВ (RIGHT), ПСТР (MID), СЦЕПИТЬ (CONCATENATE) и ее аналоги, ОБЪЕДИНИТЬ (JOINTEXT), СОВПАД (EXACT) и т.д. Этот способ хорош, если в тексте есть четкая логика (например, индекс всегда в начале адреса). В противном случае формулы существенно усложняются и, порой, дело доходит даже до формул массива, что сильно тормозит на больших таблицах.
  • Использование оператора проверки текстового подобия Like из Visual Basic, обернутого в пользовательскую макро-функцию. Это позволяет реализовать более гибкий поиск с использованием символов подстановки (*,#,? и т.д.) К сожалению, этот инструмент не умеет извлекать нужную подстроку из текста — только проверять, содержится ли она в нем.

Кроме вышеперечисленного, есть еще один подход, очень известный в узких кругах профессиональных программистов, веб-разработчиков и прочих технарей — это регулярные выражения (Regular Expressions = RegExp = «регэкспы» = «регулярки»). Упрощенно говоря, RegExp — это язык, где с помощью специальных символов и правил производится поиск нужных подстрок в тексте, их извлечение или замена на другой текст. Регулярные выражения — это очень мощный и красивый инструмент, на порядок превосходящий по возможностям все остальные способы работы с текстом. Многие языки программирования (C#, PHP, Perl, JavaScript…) и текстовые редакторы (Word, Notepad++…) поддерживают регулярные выражения.

Microsoft Excel, к сожалению, не имеет поддержки RegExp по-умолчанию «из коробки», но это легко исправить с помощью VBA. Откройте редактор Visual Basic с вкладки Разработчик (Developer) или сочетанием клавиш Alt+F11. Затем вставьте новый модуль через меню Insert — Module и скопируйте туда текст вот такой макрофункции:

Public Function RegExpExtract(Text As String, Pattern As String, Optional Item As Integer = 1) As String
    On Error GoTo ErrHandl
    Set regex = CreateObject("VBScript.RegExp")
    regex.Pattern = Pattern
    regex.Global = True
    If regex.Test(Text) Then
        Set matches = regex.Execute(Text)
        RegExpExtract = matches.Item(Item - 1)
        Exit Function
    End If
ErrHandl:
    RegExpExtract = CVErr(xlErrValue)
End Function

Теперь можно закрыть редактор Visual Basic и, вернувшись в Excel, опробовать нашу новую функцию. Синтаксис у нее следующий:

=RegExpExtract( Txt ; Pattern ; Item )

где

  • Txt — ячейка с текстом, который мы проверяем и из которого хотим извлечь нужную нам подстроку
  • Pattern — маска (шаблон) для поиска подстроки
  • Item — порядковый номер подстроки, которую надо извлечь, если их несколько (если не указан, то выводится первое вхождение)

Самое интересное тут, конечно, это Pattern — строка-шаблон из спецсимволов «на языке» RegExp, которая и задает, что именно и где мы хотим найти. Вот самые основные из них — для начала:

 Паттерн  Описание
 . Самое простое — это точка. Она обозначает любой символ в шаблоне на указанной позиции.
 s Любой символ, выглядящий как пробел (пробел, табуляция или перенос строки).
 S Анти-вариант предыдущего шаблона, т.е. любой НЕпробельный символ.
 d Любая цифра
 D Анти-вариант предыдущего, т.е. любая НЕ цифра
 w Любой символ латиницы (A-Z), цифра или знак подчеркивания
 W Анти-вариант предыдущего, т.е. не латиница, не цифра и не подчеркивание.
[символы] В квадратных скобках можно указать один или несколько символов, разрешенных на указанной позиции в тексте. Например ст[уо]л будет соответствовать любому из слов: стол или стул.
Также можно не перечислять символы, а задать их диапазоном через дефис, т.е. вместо [ABDCDEF] написать [A-F]. или вместо [4567] ввести [4-7]. Например, для обозначения всех символов кириллицы можно использовать шаблон [а-яА-ЯёЁ].
[^символы] Если после открывающей квадратной скобки добавить символ «крышки» ^, то набор приобретет обратный смысл — на указанной позиции в тексте будут разрешены все символы, кроме перечисленных. Так, шаблон [^ЖМ]уть найдет Путь или Суть или Забудь, но не Жуть или Муть, например.
 | Логический оператор ИЛИ (OR) для проверки по любому из указанных критериев. Например чет|счёт|invoice) будет искать в тексте любое из указанных слов. Обычно набор вариантов заключается в скобки.
 ^ Начало строки
 $ Конец строки
 b Край слова

Если мы ищем определенное количество символов, например, шестизначный почтовый индекс или все трехбуквенные коды товаров, то на помощь нам приходят квантификаторы или кванторы — специальные выражения, задающие количество искомых знаков. Квантификаторы применяются к тому символу, что стоит перед ним:

  Квантор  Описание
 ? Ноль или одно вхождение. Например .? будет означать один любой символ или его отсутствие.
 + Одно или более вхождений. Например d+ означает любое количество цифр (т.е. любое число от 0 до бесконечности).
 * Ноль или более вхождений, т.е. любое количество. Так s* означает любое количество пробелов или их отсутствие.
{число} или
{число1,число2}
Если нужно задать строго определенное количество вхождений, то оно задается в фигурных скобках. Например d{6} означает строго шесть цифр, а шаблон s{2,5} — от двух до пяти пробелов

Теперь давайте перейдем к самому интересному — разбору применения созданной функции и того, что узнали о паттернах на практических примерах из жизни.

Извлекаем числа из текста

Для начала разберем простой случай — нужно извлечь из буквенно-цифровой каши первое число, например мощность источников бесперебойного питания из прайс-листа:

Извлекаем первое число из текста

Логика работы регулярного выражения тут простая: d — означает любую цифру, а квантор + говорит о том, что их количество должно быть одна или больше. Двойной минус перед функцией нужен, чтобы «на лету» преобразовать извлеченные символы в полноценное число из числа-как-текст.

Почтовый индекс

На первый взгляд, тут все просто — ищем ровно шесть цифр подряд. Используем спецсимвол d для цифры и квантор {6} для количества знаков:

Извлекаем почтовый индекс

Однако, возможна ситуация, когда левее индекса в строке стоит еще один большой набор цифр подряд (номер телефона, ИНН, банковский счет и т.д.) Тогда наша регулярка выдернет из нее первых 6 цифр, т.е. сработает некорректно:

Ошибочное извлечение индекса

Чтобы этого не происходило, необходимо добавить в наше регулярное выражение по краям модификатор b означающий конец слова. Это даст понять Excel, что нужный нам фрагмент (индекс) должен быть отдельным словом, а не частью другого фрагмента (номера телефона):

Извлекаем ровно 6-разрядное число

Телефон

Проблема с нахождением телефонного номера среди текста состоит в том, что существует очень много вариантов записи номеров — с дефисами и без, через пробелы, с кодом региона в скобках или без и т.д. Поэтому, на мой взгляд, проще сначала вычистить из исходного текста все эти символы с помощью нескольких вложенных друг в друга функций ПОДСТАВИТЬ (SUBSTITUTE), чтобы он склеился в единое целое, а потом уже примитивной регуляркой d{11} вытаскивать 11 цифр подряд:

Вытаскиваем номер телефона из текста

ИНН

Тут чуть сложнее, т.к. ИНН (в России) бывает 10-значный (у юрлиц) или 12-значный (у физлиц). Если не придираться особо, то вполне можно удовлетвориться регуляркой d{10,12}, но она, строго говоря, будет вытаскивать все числа от 10 до 12 знаков, т.е. и ошибочно введенные 11-значные. Правильнее будет использовать два шаблона, связанных логическим ИЛИ оператором | (вертикальная черта):

Извлечение ИНН из текстовой строки

Обратите внимание, что в запросе мы сначала ищем 12-разрядные, и только потом 10-разрядные числа. Если же записать нашу регулярку наоборот, то она будет вытаскивать для всех, даже длинных 12-разрядных ИНН, только первые 10 символов. То есть после срабатывания первого условия дальнейшая проверка уже не производится:

Некорректное извлечение ИНН

Это принципиальное отличие оператора | от стандартной экселевской логической функции ИЛИ (OR), где от перестановки аргументов результат не меняется.

Артикулы товаров

Во многих компаниях товарам и услугам присваиваются уникальные идентификаторы — артикулы, SAP-коды, SKU и т.д. Если в их обозначениях есть логика, то их можно легко вытаскивать из любого текста с помощью регулярных выражений. Например, если мы знаем, что наши артикулы всегда состоят из трех заглавных английских букв, дефиса и последующего трехразрядного числа, то:

Артикулы

Логика работы шаблона тут проста. [A-Z] — означает любые заглавные буквы латиницы. Следующий за ним квантор {3} говорит о том, что нам важно, чтобы таких букв было именно три. После дефиса мы ждем три цифровых разряда, поэтому добавляем на конце d{3}

Денежные суммы

Похожим на предыдущий пункт образом, можно вытаскивать и цены (стоимости, НДС…) из описания товаров. Если денежные суммы, например, указываются через дефис, то:

Извлечь стоимость (цену) из текста

Паттерн d с квантором + ищет любое число до дефиса, а d{2} будет искать копейки (два разряда) после.

Если нужно вытащить не цены, а НДС, то можно воспользоваться третьим необязательным аргументом нашей функции RegExpExtract, задающим порядковый номер извлекаемого элемента. И, само-собой, можно заменить функцией ПОДСТАВИТЬ (SUBSTITUTE) в результатах дефис на стандартный десятичный разделитель и добавить двойной минус в начале, чтобы Excel интерпретировал найденный НДС как нормальное число:

Извлекаем суммы и НДС из текста

Автомобильные номера

Если не брать спецтранспорт, прицепы и прочие мотоциклы, то стандартный российский автомобильный номер разбирается по принципу «буква — три цифры — две буквы — код региона». Причем код региона может быть 2- или 3-значным, а в качестве букв применяются только те, что похожи внешне на латиницу. Таким образом, для извлечения номеров из текста нам поможет следующая регулярка:

Извлекаем автомобильный номер из текста

Время

Для извлечения времени в формате ЧЧ:ММ подойдет такое регулярное выражение:

Извлекаем время из текста

После двоеточия фрагмент [0-5]d, как легко сообразить, задает любое число в интервале 00-59. Перед двоеточием в скобках работают два шаблона, разделенных логическим ИЛИ (вертикальной чертой):

  • [0-1]d — любое число в интервале 00-19
  • 2[0-3] — любое число в интервале 20-23

К полученному результату можно применить дополнительно еще и стандартную Excel’евскую функцию ВРЕМЯ (TIME), чтобы преобразовать его в понятный программе и пригодный для дальнейших расчетов формат времени.

Проверка пароля

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

Проверку можно организовать с помощью вот такой несложной регулярки:

Проверка пароля регулярным выражением

По сути, таким шаблоном мы требуем, чтобы между началом (^) и концом ($) в нашем тексте находились только символы из заданного в квадратных скобках набора. Если нужно проверить еще и длину пароля (например, не меньше 6 символов), то квантор + можно заменить на интервал «шесть и более» в виде {6,}:

Проверка длины пароля

Город из адреса

Допустим, нам нужно вытащить город из строки адреса. Поможет регулярка, извлекающая текст от «г.» до следующей запятой:

Извлечь город из адреса

Давайте разберем этот шаблон поподробнее.

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

Следующих два символа в нашем шаблоне — точка и звездочка-квантор — обозначают любое количество любых символов, т.е. любое название города.

На конце шаблона стоит запятая, т.к. мы ищем текст от «г.» до запятой. Но ведь в тексте может быть несколько запятых, правда? Не только после города, но и после улицы, дома и т.д. На какой из них будет останавливаться наш запрос? Вот за это отвечает вопросительный знак. Без него наша регулярка вытаскивала бы максимально длинную строку из всех возможных:

Извлекаем город из адреса - жадный квантор

В терминах регулярных выражений, такой шаблон является «жадным». Чтобы исправить ситуацию и нужен вопросительный знак — он делает квантор, после которого стоит, «скупым» — и наш запрос берет текст только до первой встречной запятой после «г.»:

Скупой квантор

Имя файла из полного пути

Еще одна весьма распространенная ситуация — вытащить имя файла из полного пути. Тут поможет простая регулярка вида:

Извлечь имя файла из полного пути

Тут фишка в том, что поиск, по сути, происходит в обратном направлении — от конца к началу, т.к. в конце нашего шаблона стоит $, и мы ищем все, что перед ним до первого справа обратного слэша. Бэкслэш заэкранирован, как и точка в предыдущем примере.

P.S.

«Под занавес» хочу уточнить, что все вышеописанное — это малая часть из всех возможностей, которые предоставляют регулярные выражения. Спецсимволов и правил их использования очень много и на эту тему написаны целые книги (рекомендую для начала хотя бы эту). В некотором смысле, написание регулярных выражений — это почти искусство. Почти всегда придуманную регулярку можно улучшить или дополнить, сделав ее более изящной или способным работать с более широким диапазоном вариантов входных данных.

Для анализа и разбора чужих регулярок или отладки своих собственных есть несколько удобных онлайн-сервисов: RegEx101, RegExr и др.

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

Если же вы не новичок в теме, и вам есть чем поделиться — оставляйте полезные при работе в Excel регулярки в комментариях ниже. Один ум хорошо, а два сапога — пара!

Ссылки по теме

  • Замена и зачистка текста функцией ПОДСТАВИТЬ (SUBSTITUTE)
  • Поиск и подсветка символов латиницы в русском тексте
  • Поиск ближайшего похожего текста (Иванов = Ивонов = Иваноф и т.д.)

You can use text functions to manipulate text strings in Excel. However, you can’t use them with regular expressions. As of writing this article VBA is your only option. In this guide, we’re going to show you how to use regular expressions in Excel.

Download Workbook

What is a regular expression?

A regular expression (also known as regex or regexp shortly) is a special text string for specifying a search pattern. They are like wildcards. Instead of specifying the number of characters, you can create patterns to find a specific group of characters, like searching between «b» to «o», using OR logic, excluding some characters, or repeating values.

Regular expressions are commonly used for text parsing and replacing operations for all programming languages. To use regular expressions in Excel, we will be using VBA.

Pattern Description Samples
^jack begins with «jack» jack-of-all-trades, jack’s house
jack$ ends with «jack» hijack
^jack$ is exactly «jack» jack
colo[u]{0,}r can include «u» at least 0 times colour, color (not colur)
col[o|u]r includes either «o» or «u» color, colur (not colour)
col[^u]r accepts any character except «u» color (not colur or colour)

How to use regular expressions

Let’s start using regular expressions in Excel by opening VBA. Press Alt + F11 keys to open VBA (Visual Basic for Applications) window. Add a module to enter your code.

Next step is to add regular expression reference to VBA. Click Tools > References in the VBA toolbar. Find and check Microsoft VBScript Regular Expressions 5.5 item in the References window. Click OK to add the reference.

How to use regular expressions in Excel 02

Using the VBScript reference, we can create a regular expression object, which is defined as RegExp in VBA. A RegExp object has 4 properties and 3 methods:

Properties

Name Type Description
Global Boolean Set True to find all cases that match with the pattern.
Set False to find the first match.
IgnoreCase Boolean Set True to not make case-sensitive search.
Set False to make case-sensitive search.
Multiline Boolean Set True if your string has multiple lines and you want to perform the search in all lines.
Pattern String The regular expression pattern you want to search.

Methods

Name Arguments Description
Execute sourceString As String Returns an array that contains all occurrences of the pattern matched in the string.
Replace sourceString As String replaceVar As Variant Returns a string which all occurrences of the pattern in the string are replaced with the replaceVar string.
Test sourceString As String Returns True if there is a match. Otherwise, False.

Code Samples

A function that returns TRUE/FALSE if the pattern is found in a string

Public Function RegExFind(str As String, pat As String) As Boolean

‘Define the regular expression object

Dim RegEx As New RegExp

‘Set up regular expression properties

With RegEx

.Global = False ‘All occurences are not necessary since a single occurence is enough

.IgnoreCase = True ‘No case-sensitivty

.MultiLine = True ‘Check all lines

.Pattern = pat ‘pattern

End With

RegExFind = RegEx.Test(str)

End Function

How to use regular expressions in Excel 04

After writing the code, you can use this function as a regular Excel function.

A function that replaces the pattern with a given string

Public Function RegExReplace(str As String, pat As String, replaceStr As String) As String

‘Define the regular expression object

Dim RegEx As New RegExp

‘Set up regular expression properties

With RegEx

.Global = False ‘All occurences are not necessary since a single occurence is enough

.IgnoreCase = True ‘No case-sensitivty

.MultiLine = True ‘Check all lines

.Pattern = pat ‘pattern

End With

RegExReplace = RegEx.Replace(str, replaceStr) ‘Return the modified string with replacement value

End Function

How to use regular expressions in Excel 06

The following sample shows how to replace strings that start with «col», continue with 0 or 1 occurrences of «o» and single «u», and finally ends with an «r» character with «Color» string.

In this Article

  • What is Regex?
  • Matching Characters
  • Quantifiers
  • Grouping
  • How to Use Regex in VBA
  • Testing a Pattern for a Match Against a String
  • Replacing a Pattern in a String
  • Matching and Displaying a Pattern in a String

This tutorial will demonstrate how to use Regex in VBA.

What is Regex?

Regex stands for regular expression. A regular expression is a pattern made up of a sequence of characters that you can use to find a matching pattern in another string. In order to use Regex in VBA you have to use the RegExp object.

A pattern such as [A-C] can be used to search for and match an upper case letter from A to C from a sequence. Regex patterns have their own syntax and can be built using a character or sequence of characters.

Matching Characters

The following table shows the syntax which will allow you to build Regex patterns.

Pattern Syntax Description Example Matches Found
. Matches any single character except vbNewLine f.n fan, fon, f@n, fwn
[characters] Matches any single character between brackets[] [fn] Would only match “f” or “n” in fan
[^characters] Matches any single character that is not between brackets[] [^fn] So would match “j” in “fjn”
[start-end] Matches any character that is part of the range in brackets[] [1-5] Would match “4” and “5” in “45”
w Matches alphanumeric characters and the underscore, but not the space character w Would match “c” in “,c.”
W Matches any non-alphanumeric characters and the underscore W Would match “@” in “bb@bb”
s Matches any white space character such as spaces and tabs s Would match ” ” in “This is”
S Matches any non-white space character S Would match “T” and “h” in “T h”
d Matches any single decimal digit d Would match “7” in “a7h”
D Matches any single non-decimal digit D Would match j in “47j”
Escapes special characters which then allows you to search for them . Would match “.” in “59.pQ”
t Tab t Would match a tab character
r Carriage Return r Would match a carriage return (vbCr)
n vbNewLine(vbTab) n Would match a new line

Quantifiers

You can use quantifiers to specify how many times you want the pattern to match against the string.

Quantifier Description Example Matches Found
* Matches zero or more occurrences fn*a  fna, fa, fnna, fnnna, fnfnnna
+ Matches one or more occurrences fn+a fna, fnna, fnfnna
? Matches zero or one fn?a fa, fna
{n} Matches “n” many times dW{4} Would match “d….” in “d….&5hi”
{n,} Matches at least “n” number of times dW{4,} Would match “d….&” in “d….&5hi”
{n,m} Matches between n and m number of times dW{1,8} Would match “d….&&&&” in “d….&&&&5hi”

Grouping

Grouping or capturing allows you to use a pattern to capture and extract a portion of a string. So not only is the pattern matched, but the part of the string that matches the pattern is captured.

Pattern Description Example Matches Found and Captured
(expression) Groups and captures the pattern in parenthesis (W{4}) Would group and capture “@@@@” from “1@@@@1jlmba”

How to Use Regex in VBA

In order to use Regex in VBA, you first have to set the reference in the VBE editor. In the VBE editor, go to Tools > References > Microsoft VBScript Regular Expressions.

Adding the Reference For the Regex Expressions in VBA

These are the properties of the RegExp object:

  • Pattern – The pattern you are going to use for matching against the string.
  • IgnoreCase – If True, then the matching ignores letter case.
  • Global – If True, then all the matches of the pattern in the string are found. If False then only the first match is found.
  • MultiLine – If True, pattern matching happens across line breaks.

These are the methods of the RegExp object:

  • Test – Searches for a pattern in a string and returns True if a match is found.
  • Replace – Replaces the occurrences of the pattern with the replacement string.
  • Execute – Returns matches of the pattern against the string.

Testing a Pattern for a Match Against a String

You can use the Test method to check whether a pattern matches a sequence in the input string. The result is True if a match is found. The following code will show you how to test a pattern against a string:

Sub RegexTestingAPattern()

Dim stringOne As String
Dim regexOne As Object
Set regexOne = New RegExp

regexOne.Pattern = "f....a"

stringOne = "000111fjo88a8"

Debug.Print regexOne.Test(stringOne)

End Sub

The result is:

Using Regex to Test a Pattern in VBA

VBA Coding Made Easy

Stop searching for VBA code online. Learn more about AutoMacro — A VBA Code Builder that allows beginners to code procedures from scratch with minimal coding knowledge and with many time-saving features for all users!

automacro

Learn More

Replacing a Pattern in a String

You can use the Replace method to replace the first instance of a matching pattern in a string or all the instances of a matching pattern in a string. If Global is set to False, then only the first instance is replaced. The following code will show you how to replace a pattern in a string:

Sub RegexReplacingAPattern()
Dim stringOne As String
Dim regexOne As Object
Set regexOne = New RegExp

regexOne.Pattern = "This is the number"
regexOne.Global = False
stringOne = "This is the number 718901"

Debug.Print regexOne.Replace(stringOne, "That is the new number")
End Sub

The result is:

Using Regex to Replace a String in VBA

To replace only the number portion of the string used above, you would use the following code:

Sub RegexReplacingAPattern()
Dim stringOne As String
Dim regexOne As Object
Set regexOne = New RegExp

regexOne.Pattern = "[^D]+"
regexOne.Global = False
stringOne = "This is the number 718901"

Debug.Print regexOne.Replace(stringOne, "777192")
End Sub

The result is:

Replacing a number portion of a String in Regex in VBA

To replace every instance of a certain pattern in a string, you would set the global value to True. The following code shows you how to replace every instance of -A1289C- in the string:

Sub RegexReplacingEveryInstanceOfAPattern()
Dim stringOne As String
Dim regexOne As Object
Set regexOne = New RegExp

regexOne.Pattern = "WAd+CW"
regexOne.Global = True
stringOne = "ABC-A1289C-ABC-A1289C-ABC"

Debug.Print regexOne.Replace(stringOne, "IJK")
End Sub

Replacing Every Instance of a String with Regex in VBA

Matching and Displaying a Pattern in a String

You can use the Execute method to match one or all instances of a pattern within a string. The following code shows you how to match and  display all instances of the pattern from the string:

Sub RegexMatchingAndDisplayingAPattern()
Dim stringOne As String
Dim regexOne As Object
Dim theMatches As Object
Dim Match As Object
Set regexOne = New RegExp

regexOne.Pattern = "A.C"
regexOne.Global = True
regexOne.IgnoreCase = True
stringOne = "ABC-A1289C-ADC-A1289C-AJC"

Set theMatches = regexOne.Execute(stringOne)

For Each Match In theMatches
  Debug.Print Match.Value
Next

End Sub

The result is:

Matching and Capturing all the Patterns in a String Using Regex

Let’s say we only wanted to match -ADC- from the above string. The following code shows how to match and display only  -ADC- from the string:

Sub RegexMatchingAndDisplayingAPattern()
Dim stringOne As String
Dim regexOne As Object
Dim theMatches As Object
Dim Match As Object
Set regexOne = New RegExp

regexOne.Pattern = "-A.C-"
regexOne.Global = False
regexOne.IgnoreCase = True
stringOne = "ABC-A1289C-ADC-A1289C-AEC"

Set theMatches = regexOne.Execute(stringOne)

For Each Match In theMatches
  Debug.Print Match.Value
Next

End Sub

Capturing a Pattern in Regex VBA

Regex can take some time to learn, but it’s an extremely powerful tool for identifying/manipulating strings of text. It’s also broadly used across programming languages.

Понравилась статья? Поделить с друзьями:
  • Регулярные выражения excel что это
  • Регулярные выражения excel фильтр
  • Регулярные выражения excel или
  • Регрессия с фиктивными переменными в excel
  • Регрессия с двумя переменными в excel