Excel Regex: porovnávanie reťazcov pomocou regulárnych výrazov

  • Zdieľajte To
Michael Brown

V tomto návode sa podrobne pozrieme na to, ako používať regex na porovnávanie reťazcov v programe Excel.

Keď potrebujete nájsť určitú hodnotu v rozsahu buniek, použijete funkciu MATCH alebo XMATCH. Pri hľadaní konkrétneho reťazca v bunke sa hodia funkcie FIND a SEARCH. A ako zistíte, či bunka obsahuje informácie, ktoré zodpovedajú danému vzoru? Samozrejme, pomocou regulárnych výrazov. Excel však po vybalení z krabice nepodporuje regexy! Bez obáv, prinútime ho k tomu :)

    Funkcia Excel VBA Regex na porovnávanie reťazcov

    Ako je z nadpisu zrejmé, na používanie regulárnych výrazov v programe Excel je potrebné vytvoriť vlastnú funkciu. Našťastie má Excel vo VBA zabudovanú funkciu RegExp objekt, ktorý môžete použiť vo svojom kóde, ako je uvedené nižšie:

    Public Function RegExpMatch(input_range As Range, pattern As String , Optional match_case As Boolean = True ) As Variant Dim arRes() As Variant 'pole na uloženie výsledkov Dim iInputCurRow, iInputCurCol, cntInputRows, cntInputCols As Long 'index aktuálneho riadku v zdrojovom rozsahu, index aktuálneho stĺpca v zdrojovom rozsahu, počet riadkov, počet stĺpcov 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

    Vložte kód do editora VBA a váš nový RegExpMatch Funkcia je pripravená na použitie. Ak nemáte veľké skúsenosti s VBA, môže vám pomôcť tento návod: Ako vložiť kód VBA do programu Excel.

    Poznámka: Po vložení kódu nezabudnite súbor uložiť ako zošit s povolenými makrami (.xlsm).

    Syntax RegExpMatch

    Stránka RegExpMatch Funkcia kontroluje, či niektorá časť zdrojového reťazca zodpovedá regulárnemu výrazu. Výsledkom je logická hodnota: TRUE, ak sa našla aspoň jedna zhoda, inak FALSE.

    Naša vlastná funkcia má 3 argumenty - prvé dva sú povinné a posledný je nepovinný:

    RegExpMatch(text, vzor, [match_case])

    Kde:

    • Text (povinné) - jeden alebo viac reťazcov, v ktorých sa má vyhľadávať. Môže byť zadaný ako odkaz na bunku alebo rozsah.
    • Vzor (povinné) - regulárny výraz, ktorý sa má porovnať. Ak je vzor umiestnený priamo vo vzorci, musí byť uzavretý v dvojitých úvodzovkách.
    • Match_case (nepovinné) - definuje typ porovnávania. Ak je TRUE alebo vynechaný (predvolené), porovnávanie rozlišuje veľké a malé písmená; ak je FALSE - nerozlišuje veľké a malé písmená.

    Funkcia funguje vo všetkých verziách programov Excel 365, Excel 2021, Excel 2019, Excel 2016, Excel 2013 a Excel 2010.

    3 veci, ktoré by ste mali vedieť o RegExpMatch

    Skôr ako prejdeme k praktickým výpočtom, všimnite si, prosím, nasledujúce body, ktoré objasňujú niektoré technické aspekty:

    1. Funkcia môže spracovať jedna bunka alebo rozsah buniek V druhom prípade sa výsledky vrátia v susedných bunkách vo forme dynamického poľa alebo rozsahu rozsypu, ako je znázornené v tomto príklade.
    2. V predvolenom nastavení je funkcia rozlišovanie veľkých a malých písmen Ak chcete ignorovať veľkosť písmen textu, nastavte match_case argument na FALSE. Z dôvodu obmedzení VBA Regexp nie je podporovaný vzor bez rozlišovania veľkých a malých písmen (?i).
    3. Ak sa nenájde platný vzor, funkcia vráti FALSE; ak sa vzor je neplatný , nastane chyba #VALUE!.

    Nižšie nájdete niekoľko príkladov zhody regexu, ktoré boli vytvorené na demonštračné účely. Nemôžeme zaručiť, že naše vzory budú bezchybne fungovať so širším rozsahom vstupných údajov v reálnych pracovných hárkoch. Pred nasadením do výroby nezabudnite otestovať a upraviť naše vzory podľa svojich potrieb.

    Ako používať regex na porovnávanie reťazcov v programe Excel

    Ak majú všetky reťazce, ktoré chcete porovnať, rovnaký vzor, ideálnym riešením sú regulárne výrazy.

    Predpokladajme, že máte rozsah buniek (A5:A9) obsahujúcich rôzne údaje o niektorých položkách. Chcete zistiť, ktoré bunky obsahujú SKU. Za predpokladu, že každý SKU pozostáva z 2 veľkých písmen, pomlčky a 3 číslic, môžete ich porovnať pomocou nasledujúceho výrazu.

    Vzor : \b[A-Z]{2}-\d{3}\b

    Kde [A-Z]{2} znamená akékoľvek 2 veľké písmená od A po Z a \d{3} znamená akékoľvek 3 číslice od 0 po 9. Znak \b označuje hranicu slova, čo znamená, že SKU je samostatné slovo a nie súčasť väčšieho reťazca, ako napríklad 23-MAR-2022.

    Po vytvorení vzoru môžeme prejsť k písaniu vzorca. Používanie vlastnej funkcie sa v podstate nelíši od natívneho vzorca. Hneď ako začnete písať vzorec, názov funkcie sa objaví v zozname navrhnutom funkciou Automatické dokončovanie programu Excel. V programe Excel s dynamickým poľom (Microsoft 365 a Excel 2021) a v tradičnom programe Excel (2019 a staršie verzie) však existuje niekoľko nuáns.

    Zhoda reťazca v jednej bunke

    Ak chcete porovnať reťazec v jednej bunke, odkážte na túto bunku v prvom argumente. Druhý argument má obsahovať regulárny výraz.

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

    Vzor môže byť uložený aj v preddefinovanej bunke, ktorá je uzamknutá absolútnym odkazom ($A$2):

    =RegExpMatch(A5, $A$2)

    Po zadaní vzorca do prvej bunky ho môžete pretiahnuť do všetkých ostatných riadkov.

    Táto metóda funguje skvele v všetky verzie programu Excel .

    Zodpovedanie reťazcov vo viacerých bunkách naraz

    Ak chcete porovnať viac reťazcov pomocou jedného vzorca, uveďte v prvom argumente odkaz na rozsah:

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

    Na stránke Excel 365 a Excel 2021 ktoré podporujú dynamické polia, to funguje tak, že do prvej bunky napíšete vzorec, stlačíte Enter a vzorec sa automaticky preleje do nasledujúcich buniek.

    Na stránke Excel 2019 a skôr, funguje len ako tradičný vzorec CSE, ktorý sa zadáva do rozsahu buniek a dokončí sa stlačením klávesov Ctrl + Shift + Enter spolu.

    Regex na porovnanie čísla

    Ak chcete priradiť akúkoľvek jednu číslicu od 0 do 9, použite \d V závislosti od konkrétnej úlohy pridajte vhodný kvantifikátor alebo vytvorte zložitejší vzor.

    Regex na porovnanie s ľubovoľným číslom

    Ak chcete priradiť ľubovoľné číslo ľubovoľnej dĺžky, vložte kvantifikátor + hneď za znak /d, ktorý hovorí, že sa majú hľadať čísla obsahujúce 1 alebo viac číslic.

    Vzor : \d+

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

    Regex na porovnanie čísla určitej dĺžky

    Ak je vaším cieľom porovnať číselné hodnoty obsahujúce určitý počet číslic, použite \d spolu s príslušným kvantifikátorom.

    Ak chcete napríklad priradiť čísla faktúr pozostávajúce presne zo 7 číslic, použite \d{7}. Nezabudnite však, že priradí 7 číslic kdekoľvek v reťazci vrátane 10-miestneho alebo 100-miestneho čísla. Ak toto nie je to, čo hľadáte, vložte na obe strany slovnú hranicu \b.

    Vzor : \b\d{7}\b

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

    Regex na porovnávanie telefónnych čísel

    Keďže telefónne čísla môžu byť zapísané v rôznych formátoch, ich porovnávanie si vyžaduje zložitejší regulárny výraz.

    V nižšie uvedenom súbore údajov budeme hľadať 10-miestne čísla, ktoré majú v prvých dvoch skupinách 3 číslice a v poslednej skupine 4 číslice. Skupiny môžu byť oddelené bodkou, pomlčkou alebo medzerou. Prvá skupina môže, ale nemusí byť uzavretá v zátvorkách.

    Vzor: (\(\d{3}\)

    Po rozklade tohto regulárneho výrazu dostaneme nasledovné:

    • Prvá časť (\(\d{3}\)
    • Časť [-\.\s]? znamená 0 alebo 1 výskyt ľubovoľného znaku v hranatých zátvorkách: pomlčky, bodky alebo bieleho znaku.
    • Ďalej je tu ešte jedna skupina 3 číslic d{3}, za ktorou nasleduje akákoľvek pomlčka, bodka alebo biely znak [\-\.\s]?, ktoré sa vyskytujú 0 alebo 1-krát.
    • Za poslednou skupinou 4 číslic \d{4} nasleduje hranica slov \b, aby bolo jasné, že telefónne číslo nemôže byť súčasťou väčšieho čísla.

    S pôvodným reťazcom v A5 a regulárnym výrazom v A2 má vzorec tento tvar:

    =RegExpMatch(A5, $A$2)

    ... a funguje presne podľa očakávania:

    Poznámky:

    • Medzinárodné kódy sa nekontrolujú, takže môžu, ale nemusia byť prítomné.
    • V regulárnych výrazoch \s znamená akýkoľvek biely znak, napríklad medzeru, tabulátor, návrat vozíka alebo nový riadok. Ak chcete povoliť iba medzery, použite [-\. ] namiesto [-\.\s].
    • Regex, ktorý NEodpovedá znaku

      Ak chcete nájsť reťazce, ktoré NEobsahujú určitý znak, môžete použiť triedy negovaných znakov [^ ], ktoré zodpovedajú všetkému, čo NIEje v zátvorkách. Napríklad:

      • [^13] sa zhoduje s akýmkoľvek jedným znakom, ktorý nie je 1 alebo 3.
      • [^1-3] zodpovedá každému jednotlivému znaku, ktorý nie je 1, 2 alebo 3 (t. j. akejkoľvek číslici od 1 do 3).

      Predpokladajme, že v zozname telefónnych čísel chcete nájsť tie, ktoré neobsahujú kód krajiny. Ak máte na pamäti, že každý medzinárodný kód obsahuje znak +, môžete na vyhľadanie reťazcov, ktoré neobsahujú znak plus, použiť triedu znakov [^\+]. Je dôležité si uvedomiť, že uvedený výraz zodpovedá každému jednotlivému znaku, ktorý nie je +. Pretože telefónne číslo môže byť kdekoľvek v reťazci, nienevyhnutne na samom začiatku, je pridaný kvantifikátor *, ktorý kontroluje každý nasledujúci znak. Kotvy na začiatku ^ a na konci $ zabezpečujú, že sa spracuje celý reťazec. Ako výsledok dostaneme nasledujúci regulárny výraz, ktorý hovorí "nezhoduje sa so znakom + na žiadnej pozícii v reťazci".

      Vzor : ^[^\+]*$

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

      Regex, ktorý nezodpovedá reťazcu

      Hoci neexistuje špeciálna syntax regulárneho výrazu pre nezhodu s konkrétnym reťazcom, môžete toto správanie napodobniť použitím záporného lookaheadu.

      Predpokladajme, že chcete nájsť reťazce, ktoré neobsahujú slovo "citróny". Tento regulárny výraz bude fungovať výborne:

      Vzor : ^(((?!citróny).)*$

      Je zrejmé, že tu je potrebné určité vysvetlenie. Záporný lookahead (?!citróny) sa pozrie doprava, aby zistil, či pred ním nie je slovo "citróny". Ak tam "citróny" nie je, potom bodka zodpovedá akémukoľvek znaku okrem zalomenia riadku. Vyššie uvedený výraz vykonáva len jednu kontrolu a kvantifikátor * ju opakuje nula alebo viackrát, od začiatku reťazca ukotveného pomocou ^ po koniec reťazca ukotveného pomocou$.

      Ak chceme ignorovať veľkosť písmen v texte, nastavíme 3. argument na FALSE, aby naša funkcia nerozlišovala veľkosť písmen:

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

      Tipy a poznámky:

      • Vyššie uvedený regex funguje len pre jednoriadkový V prípade miliriadkových reťazcov znaky ^ a $ zodpovedajú začiatku a koncu každého riadku namiesto začiatku a konca vstupného reťazca, preto regex vyhľadáva len v prvom riadku.
      • Zodpovedanie reťazcov, ktoré nezačínajte s určitým textom , použite regulárny výraz, napríklad ^(?!citróny).*$
      • Zodpovedanie reťazcov, ktoré neskončiť s určitým textom , zahrňte do vyhľadávacieho vzoru kotvu koncového reťazca: ^((?!citróny$).)*$

      Porovnávanie bez rozlišovania veľkých a malých písmen

      V klasických regulárnych výrazoch existuje špeciálny vzor pre porovnávanie bez rozlišovania veľkých a malých písmen (?i), ktorý nie je podporovaný vo VBA RegExp. Aby sme toto obmedzenie prekonali, naša vlastná funkcia akceptuje 3. voliteľný argument s názvom match_case Ak chcete vykonať porovnávanie bez rozlišovania veľkých a malých písmen, jednoducho nastavte hodnotu FALSE.

      Povedzme, že chcete identifikovať dátumy ako 1.3.22 alebo 01.3.2022. dd-mmm-rrrr a d-mmm-yy formáty, používame nasledujúci regulárny výraz.

      Vzor : \b\d{1,2}-(Jan

      Náš výraz vyhľadáva skupinu 1 alebo 2 číslic, za ktorými nasleduje pomlčka, po ktorej nasleduje niektorá zo skratiek mesiaca oddelená

      Prečo nepoužijete jednoduchší vzor, napríklad \d{1,2}-[A-Za-z]{3}-\d{2,4}\b? Aby ste predišli falošným pozitívnym zhodám, napríklad 01-ABC-2020.

      Zadajte vzor do A2 a dostanete nasledujúci vzorec:

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

      Regex na porovnanie platných e-mailových adries

      Ako je všeobecne známe, e-mailová adresa sa skladá zo 4 častí: používateľského mena, symbolu @, názvu domény (poštového servera) a domény najvyššej úrovne (napríklad .com, .edu, .org atď.). Ak chceme skontrolovať platnosť e-mailovej adresy, budeme musieť vyššie uvedenú štruktúru replikovať pomocou regulárnych výrazov.

      Vzor : \b[\w\.\-]+@[A-Za-z0-9]+[A-Za-z0-9\.\-]*[A-Za-z0-9]+\.[A-Za-z]{2,24}\b

      Aby ste lepšie pochopili, o čo tu ide, pozrime sa bližšie na jednotlivé časti:

      • Používateľské meno môže obsahovať písmená, číslice, podčiarkovníky, bodky a pomlčky. Ak si uvedomíme, že \w sa zhoduje s akýmkoľvek písmenom, číslicou alebo podčiarkovníkom, dostaneme nasledujúci regex: [\w\.\-]+
      • Názov domény môžu obsahovať veľké a malé písmená, číslice, pomlčky (ale nie na prvej alebo poslednej pozícii) a bodky (v prípade subdomén). Keďže podčiarkovníky nie sú povolené, namiesto \w používame 3 rôzne znakové sady: [A-Za-z0-9]+[A-Za-z0-9\.\-]*[A-Za-z0-9]+
      • Doména najvyššej úrovne pozostáva z bodky, za ktorou nasledujú malé a veľké písmená. Môže obsahovať 2 až 24 písmen (najdlhšia TLD, ktorá v súčasnosti existuje): \.[A-Za-z]{2,24}

      Poznámka: Vzor predpokladá, že názov domény obsahuje 2 alebo viac alfanumerických znakov.

      S pôvodným textom v A5 a vzorom v A5 má vzorec tento tvar:

      =RegExpMatch(A5, $A$2)

      Alebo môžete použiť jednoduchší regulárny výraz na overenie e-mailu so sadou malých alebo veľkých písmen:

      Vzor : \b[\w\.\-]+@[a-z0-9]+[a-z0-9\.\-]*[a-z0-9]+\.[a-z]{2,24}\b

      Vo vzorci však nerozlišujte veľké a malé písmená:

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

      Vzorec IF programu Excel so zhodou regex

      Vzhľadom na to, že vstavané a vlastné funkcie sa dobre dopĺňajú, nič vám nebráni používať ich spoločne v jednom vzorci.

      Ak chcete niečo vrátiť alebo vypočítať, ak sa regulárny výraz zhoduje, a niečo iné, ak sa nezhoduje, vložte vlastnú funkciu RegExpMatch do logického textu IF:

      IF(RegExpMatch(...), [value_if_true], [value_if_false])

      Ak napríklad reťazec v poli A5 obsahuje platnú e-mailovú adresu, môžete vrátiť odpoveď "Áno"; v opačnom prípade "Nie".

      =IF(RegExpMatch(A5, $A$2,), "Áno", "Nie")

      Počet, ak je regex zhodný

      Keďže natívne funkcie programu Excel nepodporujú regulárne výrazy, nie je možné vložiť regex priamo do funkcie COUNTIS alebo COUNTIFS. Našťastie môžete túto funkciu napodobniť pomocou našej vlastnej funkcie.

      Predpokladajme, že ste použili regex na porovnanie telefónnych čísel a výsledky ste vypisovali do stĺpca B. Ak chcete zistiť, koľko buniek obsahuje telefónne čísla, stačí spočítať hodnoty TRUE v B5:B9. A to sa dá jednoducho urobiť pomocou štandardného vzorca COUNTIF:

      =COUNTIF(B5:B9, TRUE)

      Nechcete mať v pracovnom hárku žiadne ďalšie stĺpce? Žiadny problém. Ak máte na pamäti, že naša vlastná funkcia dokáže spracovať viacero buniek naraz a súčet Excelu dokáže sčítať hodnoty v poli, urobíte toto:

      • Poskytnite odkaz na rozsah RegExpMatch, aby vrátil pole hodnôt TRUE a FALSE.
      • Použite dvojitú negáciu (--), aby ste logické hodnoty zmenili na jednotky a nuly.
      • Získajte funkciu SUM na sčítanie 1 a 0 vo výslednom poli.

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

      Porovnávanie regexov pomocou balíka Ultimate Suite

      Používatelia nášho balíka Ultimate Suite môžu využívať štyri výkonné funkcie Regex bez toho, aby museli do svojich zošitov pridávať kód VBA, pretože sú hladko integrované do programu Excel počas inštalácie doplnku. Naše vlastné funkcie sú spracované štandardným mechanizmom RegEx v sieti .NET a podporujú plnohodnotné klasické regulárne výrazy.

      Ako používať vlastnú funkciu RegexMatch

      Za predpokladu, že máte nainštalovanú najnovšiu verziu balíka Ultimate Suite (2021.4 alebo novšiu), môžete vzorec Regex Match vytvoriť v dvoch jednoduchých krokoch:

      1. Na Údaje Ablebits na karte Text kliknite na položku Nástroje Regex .

    • Na Nástroje Regex vykonajte nasledujúce kroky:
      • Vyberte zdrojové reťazce.
      • Zadajte svoj vzor.
      • Vyberte si Zápas možnosť.
      • Ak chcete, aby sa výsledky zobrazovali ako vzorce, a nie ako hodnoty, vyberte možnosť Vložiť ako vzorec začiarkavacie políčko.
      • Kliknite na tlačidlo Zápas tlačidlo.

      O chvíľu neskôr sa AblebitsRegexMatch sa vloží do nového stĺpca napravo od vašich údajov.

      Na obrázku nižšie funkcia kontroluje, či reťazce v stĺpci A obsahujú 7-miestne čísla alebo nie.

      Tipy:

      • Funkcia môže byť vložené priamo v bunke prostredníctvom štandardu Vložiť funkciu dialógové okno, kde je zaradená do kategórie AblebitsUDFs .
      • V predvolenom nastavení sa regulárny výraz pridá do vzorca, ale môžete ho ponechať aj v samostatnej bunke. Na tento účel stačí použiť odkaz na bunku pre 2. argument.
      • V predvolenom nastavení je funkcia rozlišovanie veľkých a malých písmen Pre porovnávanie bez rozlišovania veľkých a malých písmen použite vzor (?i).

      Viac informácií nájdete vo funkcii AblebitsRegexMatch.

      To je spôsob, ako v programe Excel vykonať párovanie regulárnych výrazov. Ďakujem vám za prečítanie a teším sa na vás na našom blogu budúci týždeň!

      Dostupné súbory na stiahnutie

      Príklady zhodnosti regexov Excelu (.xlsm súbor)

      14-dňová plne funkčná verzia balíka Ultimate Suite (.exe súbor)

    Michael Brown je nadšený technologický nadšenec s vášňou pre zjednodušovanie zložitých procesov pomocou softvérových nástrojov. S viac ako desaťročnými skúsenosťami v technologickom priemysle si zdokonalil svoje zručnosti v programoch Microsoft Excel a Outlook, ako aj Tabuľky Google a Dokumenty. Michaelov blog je venovaný zdieľaniu svojich vedomostí a odborných znalostí s ostatnými a poskytuje jednoduché tipy a návody na zlepšenie produktivity a efektivity. Či už ste skúsený profesionál alebo začiatočník, Michaelov blog ponúka cenné poznatky a praktické rady, ako z týchto základných softvérových nástrojov vyťažiť maximum.