Indholdsfortegnelse
I denne vejledning ser vi nærmere på, hvordan du bruger regex til at matche strenge i Excel.
Når du skal finde en bestemt værdi i en række celler, bruger du funktionen MATCH eller XMATCH. Når du leder efter en bestemt streng i en celle, er FIND- og SEARCH-funktionerne praktiske. Og hvordan ved du, om en celle indeholder oplysninger, der passer til et bestemt mønster? Naturligvis ved at bruge regulære udtryk. Men Excel understøtter ikke regexes uden videre! Bare rolig, det tvinger vi den til :)
Excel VBA Regex-funktion til at matche strenge
Som det fremgår ret tydeligt af overskriften, skal du oprette din egen funktion for at kunne bruge regulære udtryk i Excel. Heldigvis har Excels VBA en indbygget RegExp objekt, som du kan bruge i din kode som vist nedenfor:
Public Function RegExpMatch(input_range As Range, pattern As String , Optional match_case As Boolean = True ) As Variant Dim arRes() As Variant 'array til lagring af resultaterne Dim iInputCurRow, iInputCurCol, cntInputRows, cntInputCols As Long 'indeks for den aktuelle række i kildeområdet, indeks for den aktuelle kolonne i kildeområdet, antal rækker, antal kolonner 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 Next RegExpMatch = arRes Exit Function ErrHandl: RegExpMatch = CVErr(xlErrValue) End FunctionIndsæt koden i VBA-editoren, og din nye RegExpMatch Funktionen er klar til brug. Hvis du ikke har stor erfaring med VBA, kan denne vejledning være nyttig: Sådan indsætter du VBA-kode i Excel.
Bemærk. Når du har indsat koden, skal du huske at gemme din fil som en makroaktiveret arbejdsbog (.xlsm).
Syntaks for RegExpMatch
RegExpMatch funktionen kontrollerer, om en del af kildestrengen passer til et regulært udtryk. Resultatet er en boolsk værdi: TRUE, hvis der er fundet mindst ét match, og FALSE i modsat fald.
Vores brugerdefinerede funktion har 3 argumenter - de to første er obligatoriske, og det sidste er valgfrit:
RegExpMatch(text, pattern, [match_case])Hvor:
- Tekst (påkrævet) - en eller flere strenge, der skal søges i. Kan angives som en celle- eller intervalreference.
- Mønster (påkrævet) - det regulære udtryk, der skal matches. Når et mønster placeres direkte i en formel, skal det være omgivet af dobbelte anførselstegn.
- Match_case (valgfrit) - definerer matchtypen. Hvis TRUE eller udeladt (standard), udføres der en case-sensitiv matchning; hvis FALSE - case-insensitiv.
Funktionen fungerer i alle versioner af Excel 365, Excel 2021, Excel 2019, Excel 2016, Excel 2013 og Excel 2010.
3 ting, du bør vide om RegExpMatch
Før vi går over til de praktiske beregninger, skal du være opmærksom på følgende punkter, som præciserer nogle tekniske forhold:
- Funktionen kan behandle en enkeltcelle eller række af celler I sidstnævnte tilfælde returneres resultaterne i de tilstødende celler i form af et dynamisk array eller et spill-område, som vist i dette eksempel.
- Som standard er funktionen skraldefølsom Hvis du vil se bort fra tekstens kasus, skal du indstille match_case På grund af begrænsningerne i VBA Regexp understøttes ikke mønsteret (?i), der ikke tager hensyn til store og små bogstaver.
- Hvis der ikke findes et gyldigt mønster, returnerer funktionen FALSE; hvis mønsteret er ugyldigt , opstår der en #VALUE! fejl.
Nedenfor finder du nogle få eksempler på regex-match, der er oprettet til demonstrationsformål. Vi kan ikke garantere, at vores mønstre vil fungere fejlfrit med en bredere vifte af inputdata i dine rigtige regneark. Før du sætter dem i produktion, skal du sørge for at teste og justere vores eksempler på mønstre i overensstemmelse med dine behov.
Sådan bruger du regex til at matche strenge i Excel
Når alle de strenge, du ønsker at matche, har samme mønster, er regulære udtryk en ideel løsning.
Lad os antage, at du har en række celler (A5:A9), der indeholder forskellige oplysninger om nogle varer. Du vil gerne vide, hvilke celler der indeholder SKU'er. Hvis du antager, at hver SKU består af 2 store bogstaver, en bindestreg og 3 cifre, kan du matche dem ved hjælp af følgende udtryk.
Mønster : \b[A-Z]{2}-\d{3}\b
Hvor [A-Z]{2} betyder 2 store bogstaver fra A til Z og \d{3} betyder 3 cifre fra 0 til 9. \b-tegnet angiver en ordgrænse, hvilket betyder, at en SKU er et separat ord og ikke en del af en større streng som f.eks. 23-MAR-2022.
Når mønsteret er etableret, kan vi gå videre til at skrive en formel. I det væsentlige er det ikke anderledes at bruge en brugerdefineret funktion end en oprindelig funktion. Så snart du begynder at skrive en formel, vises funktionens navn på listen, som foreslås af Excels AutoComplete. Der er dog et par nuancer i Dynamic Array Excel (Microsoft 365 og Excel 2021) og traditionelt Excel (2019 og ældre versioner).
Match streng i én celle
Hvis du vil matche en streng i en enkelt celle, skal du henvise til den pågældende celle i det første argument. Det andet argument skal indeholde et regulært udtryk.
=RegExpMatch(A5, "\b[A-Z]{2}-\d{3}\b")
Mønstret kan også opbevares i en foruddefineret celle, som er låst med en absolut reference ($A$2):
=RegExpMatch(A5, $A$2)
Når du har indtastet formlen i den første celle, kan du trække den ned til alle andre rækker.
Denne metode fungerer glimrende i alle Excel-versioner .
Match strenge i flere celler på én gang
Hvis du vil matche flere strenge med en enkelt formel, skal du inkludere en intervalreference i det første argument:
=RegExpMatch(A5:A9, "\b[A-Z]{2}-\d{3}\b")
På Excel 365 og Excel 2021 der understøtter dynamiske arrays, fungerer det på denne måde - du skriver formlen i den første celle, trykker på Enter , og formlen bliver automatisk overført til de efterfølgende celler.
På Excel 2019 og tidligere fungerer den kun som en traditionel CSE-arrayformel, som indtastes i en række celler og afsluttes ved at trykke på tasterne Ctrl + Shift + Enter samtidig.
Regex til at matche nummer
Hvis du vil matche et enkelt ciffer fra 0 til 9, skal du bruge \d Alt efter din særlige opgave kan du tilføje en passende kvantifikator eller oprette et mere komplekst mønster.
Regex til at matche et vilkårligt tal
Hvis du vil matche et tal af en hvilken som helst længde, skal du sætte +-kvantifikatoren lige efter /d-tegnet, som siger, at du skal søge efter tal, der indeholder 1 eller flere cifre.
Mønster : \d+
=RegExpMatch(A5:A9, "\d+")
Regex til at matche tal af en bestemt længde
Hvis dit mål er at matche numeriske værdier, der indeholder et bestemt antal cifre, skal du bruge \d sammen med en passende kvantificerende faktor.
Hvis du f.eks. vil matche fakturanumre, der består af præcis 7 cifre, skal du bruge \d{7}. Husk dog, at det vil matche 7 cifre overalt i strengen, herunder et 10- eller 100-cifret tal. Hvis det ikke er det, du leder efter, skal du sætte ordgrænsen \b på begge sider.
Mønster : \b\d{7}\b
=RegExpMatch(A5:A9, "\b\d{7}\b")
Regex til at matche telefonnumre
Da telefonnumre kan være skrevet i forskellige formater, kræver det et mere sofistikeret regulært udtryk at matche dem.
I nedenstående datasæt søger vi efter 10-cifrede tal, der har 3 cifre i de to første grupper og 4 cifre i den sidste gruppe. Grupperne kan adskilles med punktum, bindestreg eller mellemrum. Den første gruppe kan være omsluttet af parenteser eller ej.
Mønster: (\(\(\d{3}\)\)
Hvis vi nedbryder dette regulære udtryk, får vi følgende:
- Den første del (\(\(\d{3}\)
- Delen [-\.\s]? betyder 0 eller 1 forekomst af et tegn i firkantede parenteser: bindestreg, punktum eller whitespace.
- Dernæst er der endnu en gruppe på 3 cifre d{3} efterfulgt af en bindestreg, et punktum eller et mellemrum [\-\.\s]? som optræder 0 eller 1 gang.
- Den sidste gruppe på 4 cifre \d{4} er efterfulgt af en ordgrænse \b for at gøre det klart, at et telefonnummer ikke kan være en del af et større nummer.
Med den oprindelige streng i A5 og det regulære udtryk i A2 har formlen følgende formular:
=RegExpMatch(A5, $A$2)
... og fungerer præcis som forventet:
Bemærkninger:
- Internationale koder er ikke kontrolleret, så de kan være til stede eller ej.
- I regulære udtryk står \s for et hvilket som helst tegn med mellemrum, f.eks. et mellemrum, tabulator, vognrum eller en ny linje. Hvis du kun vil tillade mellemrum, skal du bruge [-\. ] i stedet for [-\.\s].
- [^13] passer til ethvert enkelt tegn, der ikke er 1 eller 3.
- [^1-3] passer til ethvert enkelt tegn, der ikke er 1, 2 eller 3 (dvs. ethvert ciffer fra 1 til 3).
- Ovenstående regex fungerer kun for enkelt linje I tilfælde af milti-linjestrenge passer ^- og $-tegnene til begyndelsen og slutningen af hver linje i stedet for begyndelsen og slutningen af indtastningsstrengen, og derfor søger regex'en kun på den første linje.
- For at matche strenge, der ikke starte med en bestemt tekst , brug et regulært udtryk som ^(?!lemons).*$
- For at matche strenge, der ikke ophører med en bestemt tekst , medtag endestrengen ankeret i søgemønstret: ^((((?!lemons$).)*$
- Brugernavn kan indeholde bogstaver, tal, understregninger, prikker og bindestreger. Da \w passer til alle bogstaver, tal og understregninger, får vi følgende regex: [\ww\.\-]+
- Domænenavn kan indeholde store og små bogstaver, cifre, bindestreger (men ikke i første eller sidste position) og prikker (i tilfælde af subdomæner). Da understregninger ikke er tilladt, bruger vi i stedet for \w 3 forskellige tegnsæt: [A-Za-z0-9]+[A-Za-z0-9\.\-]*[A-Za-z0-9]+[A-Za-z0-9]+[A-Za-z0-9]+
- Top-level domæne består af et punkt efterfulgt af store og små bogstaver og kan indeholde mellem 2 og 24 bogstaver (det længste TLD, der findes i øjeblikket): \.[A-Za-z]{2,24}
- Angiv en intervalreference til RegExpMatch, så den returnerer et array af TRUE- og FALSE-værdier.
- Brug en dobbelt negation (--) til at tvinge de logiske værdier til at være ettere og nuller.
- Få funktionen SUM til at lægge 1'er og 0'er sammen i det resulterende array.
- På den Ablebits Data under fanen, i fanen Tekst gruppe, klik på Regex-værktøjer .
- På den Regex-værktøjer skal du gøre følgende:
- Vælg kildestrengene.
- Indtast dit mønster.
- Vælg den Match mulighed.
- Hvis du vil have resultaterne som formler og ikke som værdier, skal du vælge Indsæt som en formel afkrydsningsfeltet.
- Klik på den Match knap.
- Funktionen kan være indsat direkte i en celle via standard Indsæt funktion dialogboksen, hvor den er kategoriseret under AblebitsUDF'er .
- Som standard tilføjes et regulært udtryk til formlen, men du kan også beholde det i en separat celle. Du skal blot bruge en cellehenvisning til det andet argument.
- Som standard er funktionen skraldefølsom Hvis du ønsker at skelne mellem store og små bogstaver, skal du bruge mønsteret (?i).
Regex til IKKE at matche tegn
Hvis du vil finde strenge, der IKKE indeholder et bestemt tegn, kan du bruge negerede tegnklasser [^ ], der matcher alt, hvad der IKKE står i parentes:
Lad os antage, at du i en liste over telefonnumre ønsker at finde dem, der ikke har en landekode. Hvis du husker på, at enhver international kode indeholder +-tegnet, kan du bruge tegnklassen [^\+] til at finde strenge, der ikke indeholder et plustegn. Det er vigtigt at være opmærksom på, at ovenstående udtryk matcher ethvert enkelt tegn, der ikke er +. Da et telefonnummer kan være hvor som helst i en streng, er det ikkenødvendigvis i begyndelsen, tilføjes kvantifikatoren * for at kontrollere hvert efterfølgende tegn. Start- ^- og slut-$-ankeret sikrer, at hele strengen behandles. Som resultat får vi nedenstående regulære udtryk, der siger "match ikke +-tegnet i nogen position i strengen".
Mønster : ^[^\+]*$
=RegExpMatch(A5, "^[^[^\+]*$")
Regex til IKKE at matche streng
Selv om der ikke findes nogen særlig syntaks for regulære udtryk, der ikke matcher en bestemt streng, kan du efterligne denne adfærd ved at bruge en negativ lookahead.
Hvis du ønsker at finde strenge, der ikke indeholder ordet "lemons". Dette regulære udtryk vil fungere fint:
Mønster : ^(((?!citroner).)*$
Der er naturligvis brug for en forklaring her. Den negative lookahead (?!lemons) kigger til højre for at se, om der ikke er noget ord "lemons" foran. Hvis "lemons" ikke er der, så matcher prikken ethvert tegn undtagen et linjeskift. Ovenstående udtryk udfører kun én kontrol, og *-kvantifikatoren gentager den nul eller flere gange, fra starten af den streng, der er forankret med ^, til slutningen af den streng, der er forankret med$.
For at ignorere tekstens kasus, sætter vi det tredje argument til FALSE for at gøre vores funktion ufølsom over for kasus:
=RegExpMatch(A5, $A$2, FALSE)
Tips og noter:
Overensstemmelse uden hensyn til store og små bogstaver
I klassiske regulære udtryk er der et særligt mønster til at matche uden hensyn til store og små bogstaver (?i), hvilket ikke understøttes i VBA RegExp. For at overvinde denne begrænsning accepterer vores brugerdefinerede funktion det tredje valgfrie argument ved navn match_case Hvis du ønsker at foretage en case-insensitive matching, skal du blot indstille den til FALSE.
Lad os sige, at du ønsker at identificere datoer som f.eks. 1-Mar-22 eller 01-MAR-2022. For at matche den dd-mmm-yyyy og d-mmm-yy formater, bruger vi følgende regulære udtryk.
Mønster : \b\d{1,2}-(Jan
Vores udtryk søger efter en gruppe af 1 eller 2 cifre efterfulgt af en bindestreg, efterfulgt af en af månedens forkortelser adskilt af
Hvorfor ikke bruge et mere simpelt mønster som \d{1,2}-[A-Za-z]{3}-\d{2,4}\b? For at undgå falske positive matches som 01-ABC-2020.
Indtast mønsteret i A2, og du får følgende formel:
=RegExpMatch(A5, $A$2, FALSE)
Regex til at matche gyldige e-mail-adresser
Som det er almindeligt kendt, består en e-mail-adresse af 4 dele: brugernavn, @-symbol, domænenavn (mailserver) og topdomæne (f.eks. .com, .edu, .org osv.). For at kontrollere e-mail-adressens gyldighed skal vi kopiere ovenstående struktur ved hjælp af regulære udtryk.
Mønster : \b[\w\.\-]+@[A-Za-z0-9]+[A-Za-z0-9\.\-]*[A-Za-z0-9]+\.[A-Za-z]{2,24}\b
For bedre at forstå, hvad der foregår her, skal vi se nærmere på de enkelte dele:
Bemærk. Mønstret forudsætter, at domænenavnet indeholder 2 eller flere alfanumeriske tegn.
Med den oprindelige tekst i A5 og mønsteret i A5 får formlen denne form:
=RegExpMatch(A5, $A$2)
Du kan også bruge et mere simpelt regulært udtryk til e-mailvalidering med enten små eller store bogstaver:
Mønster : \b[\w\.\-]+@[a-z0-9]+[a-z0-9\.\-]*[a-z0-9]+\.[a-z]{2,24}\b
Men gør din formel uafhængig af store og små bogstaver:
=RegExpMatch(A5, $A$2, FALSE)
Excel IF-formel med match regex
Da indbyggede og brugerdefinerede funktioner passer godt sammen, er der intet, der forhindrer dig i at bruge dem sammen i en enkelt formel.
Hvis du vil returnere eller beregne noget, hvis et regulært udtryk er matchet, og noget andet, hvis det ikke er matchet, skal du indlejre den brugerdefinerede RegExpMatch-funktion i den logiske tekst i IF:
IF(RegExpMatch(....), [value_if_true], [value_if_false])Hvis en streng i A5 f.eks. indeholder en gyldig e-mail-adresse, kan du returnere "Ja", ellers "Nej".
=IF(RegExpMatch(A5, $A$2,), "Ja", "Nej")
Tæller, hvis regex er matchet
Da Excel-funktioner ikke understøtter regulære udtryk, er det ikke muligt at indsætte en regex direkte i funktionen COUNTIS eller COUNTIFS. Heldigvis kan du emulere denne funktionalitet ved hjælp af vores brugerdefinerede funktion.
Lad os antage, at du har brugt en regex til at matche telefonnumre og outputte resultaterne i kolonne B. For at finde ud af, hvor mange celler der indeholder telefonnumre, skal du blot tælle de sande værdier i B5:B9. Og det kan nemt gøres ved hjælp af standardformlen COUNTIF:
=COUNTIF(B5:B9, TRUE)
Hvis du ikke ønsker ekstra kolonner i dit regneark, er det ikke noget problem. Når du husker på, at vores brugerdefinerede funktion kan behandle flere celler ad gangen, og at Excels SUM kan lægge værdierne i et array sammen, skal du gøre følgende:
=SUM(--RegExpMatch(A5:A9, $A$2))
Regex matching med Ultimate Suite
Brugerne af vores Ultimate Suite kan udnytte fire kraftfulde Regex-funktioner uden at tilføje VBA-kode til deres arbejdsmapper, da de integreres problemfrit i Excel under installationen af tilføjelsesprogrammet. Vores brugerdefinerede funktioner behandles af standard .NET RegEx-motoren og understøtter klassiske regulære udtryk med alle funktioner.
Sådan bruger du en brugerdefineret RegexMatch-funktion
Hvis du har den nyeste version af Ultimate Suite installeret (2021.4 eller nyere), kan du oprette en Regex Match-formel i to enkle trin:
Et øjeblik efter blev den AblebitsRegexMatch funktionen indsættes i en ny kolonne til højre for dine data.
I skærmbilledet nedenfor kontrollerer funktionen, om strengene i kolonne A indeholder 7-cifrede tal eller ej.
Tips:
Du kan finde flere oplysninger under AblebitsRegexMatch-funktionen.
Det er sådan man laver regulære udtryksmatchning i Excel. Jeg takker dig for din læsning og glæder mig til at se dig på vores blog i næste uge!
Tilgængelige downloads
Excel Regex Match-eksempler (.xlsm-fil)
Ultimate Suite 14-dages fuldt funktionsdygtig version (.exe-fil)