Javascript-regulære uttrykk sjekker etter et tall. Eksempel: fjerning av store bokstaver

JavaScript regexp er en objekttype som brukes til å matche sekvenser av tegn i strenger.

Opprette det første regulære uttrykket

Det er to måter å lage et regulært uttrykk på: ved å bruke et regulært uttrykk bokstavelig eller ved å bruke en regulært uttrykksbygger. Hver av dem representerer det samme mønsteret: symbolet " c", etterfulgt av " en"og deretter symbolet" t».

// regulært uttrykk bokstavelig er omgitt av skråstreker (/)
var alternativ1 = /cat/;
// Konstruktør for regulære uttrykk
var option2 = new RegExp("katt");

Som en generell regel, hvis det regulære uttrykket skal være konstant, noe som betyr at det ikke vil endres, er det bedre å bruke et regulært uttrykk bokstavelig. Hvis det vil endre seg eller avhenge av andre variabler, er det bedre å bruke en metode med en konstruktør.

RegExp.prototype.test() metode

Husker du da jeg sa at regulære uttrykk er objekter? Det betyr at de har en rekke metoder. Den enkleste metoden er JavaScript regexp test som returnerer en boolsk verdi:

Sant: Strengen inneholder et regulært uttrykksmønster.

False: Ingen treff funnet.

console.log(/cat/.test(“katten sier mjau”));
// Ikke sant
console.log(/cat/.test(“hunden sier bjeff”));
// stemmer ikke

Grunnleggende jukseark for regulære uttrykk

Hemmeligheten med regulære uttrykk er å huske vanlige karakterer og grupper. Jeg anbefaler på det sterkeste å bruke noen timer på diagrammet nedenfor og deretter komme tilbake og studere videre.

Symboler

  • . – (prikk) samsvarer med et enkelt tegn med unntak av linjeskift;
  • *  –  matcher det forrige uttrykket, som gjentas 0 eller flere ganger;
  • +  –  matcher et tidligere uttrykk som gjentas 1 eller flere ganger;
  • ? – det forrige uttrykket er valgfritt ( kamper 0 eller 1 gang);
  • ^ – tilsvarer begynnelsen av linjen;
  • $ – samsvarer med slutten av linjen.

Karaktergrupper

  • d– matcher ethvert enkelt numerisk tegn.
  • w– matcher et hvilket som helst tegn (tall, bokstav eller understrek).
  • [XYZ]– et sett med tegn. Matcher ethvert enkelt tegn fra settet spesifisert i parentes. Du kan også spesifisere tegnområder, for eksempel .
  • [XYZ]+– matcher et tegn fra et sett som gjentas en eller flere ganger.
  • [^A–Å]– i et tegnsett brukes “^” som et negasjonstegn. I i dette eksemplet Mønsteret samsvarer med alt som ikke er en stor bokstav.

Flagg:

Det er fem valgfrie flagg i JavaScript regexp. De kan brukes hver for seg eller sammen, og plasseres etter den avsluttende skråstreken. For eksempel: /[ A-Z]/g. Her vil jeg bare vise to flagg.

g– globalt søk.

Jeg– Søk som ikke skiller mellom store og små bokstaver.

Ytterligere design

(x)–  fange parenteser. Dette uttrykket samsvarer med x og husker det samsvaret slik at du kan bruke det senere.

(?:x)– ikke-fangende parenteser. Uttrykket samsvarer med x, men husker ikke samsvaret.

Matcher bare x hvis den blir fulgt av y.

La oss teste materialet vi har studert

Først, la oss teste alt ovenfor. La oss si at vi vil sjekke en streng for alle tall. For å gjøre dette kan du bruke "d"-konstruksjonen.

console.log(/d/.test("12-34"));
// Ikke sant

Koden ovenfor returnerer true hvis det er minst ett siffer i strengen. Hva skal du gjøre hvis du trenger å sjekke en streng for samsvar med formatet? Du kan bruke flere "d"-tegn for å definere formatet:

console.log(/dd-dd/.test("12-34"));
//Ikke sant
console.log(/dd-dd/.test("1234"));
//feil

Hvis du ikke bryr deg om hvordan tallene kommer før og etter "-"-tegnet i JavaScript regexp online, kan du bruke "+"-symbolet for å vise at "d"-mønsteret forekommer en eller flere ganger:

console.log(/d+-d+/.test("12-34"));
// Ikke sant
console.log(/d+-d+/.test("1-234"));
// Ikke sant
console.log(/d+-d+/.test("-34"));
// stemmer ikke

For enkelhets skyld kan du bruke parenteser til å gruppere uttrykk. La oss si at vi har en katt som mjauer og vi vil sjekke mønsteret " mjau"(mjau):

console.log(/me+(ow)+w/.test("meeeeowowoww"));
// Ikke sant

La oss nå finne ut av det.

m => samsvarer med én bokstav 'm';

e + => samsvarer med bokstaven "e" en eller flere ganger;

(ow) + => samsvarer med bokstavene "ow" en eller flere ganger;

w => samsvarer med bokstaven 'w';

'm' + 'eeee' + 'owowow' + 'w'.

Når operatorer som "+" brukes umiddelbart etter parentes, påvirker de hele innholdet i parentesene.

Operatør "? " Det indikerer at det forrige tegnet er valgfritt. Som du vil se nedenfor, returnerer begge testtilfellene sanne fordi "s"-tegnene er merket som valgfrie.

console.log(/cats? sier?/i.test("katten sier mjau"));
//Ikke sant
console.log(/cats? sier?/i.test("kattene sier mjau"));
//Ikke sant

Hvis du vil finne en skråstrek, må du unnslippe den ved å bruke en omvendt skråstrek. Det samme gjelder andre tegn som har spesiell betydning, for eksempel spørsmålstegnet. Her er et JavaScript-regexp-eksempel på hvordan du ser etter dem:

var slashSearch = ///;
var questionSearch = /?/;

  • d er det samme som: hver konstruksjon tilsvarer et digitalt symbol.
  • w– dette er det samme som [ A —Za —z 0-9_]: Begge uttrykkene samsvarer med et enkelt alfanumerisk tegn eller understrek.

Eksempel: legge til mellomrom til kamel-stil linjer

I dette eksemplet er vi virkelig lei av kamel-skrivestilen, og vi trenger en måte å legge til mellomrom mellom ordene. Her er et eksempel:

removeCc("camelCase") // => skal returnere "camel Case"

Det er en enkel løsning ved å bruke et regulært uttrykk. Først må vi finne alt store bokstaver. Dette kan gjøres ved å bruke et tegnsettoppslag og en global modifikator.

Dette samsvarer med tegnet "C" i "camelCase"

Nå, hvordan legge til et mellomrom før "C"?

Vi må bruke fengslende parenteser! De lar deg finne en match og huske den for å bruke den senere! Bruk hakeparenteser for å huske den store bokstaven du finner:

Du kan få tilgang til den fangede verdien senere slik:

Ovenfor bruker vi $1 for å få tilgang til den fangede verdien. Forresten, hvis vi hadde to sett med fangeparenteser, ville vi brukt $1 og $2 for å referere til de fangede verdiene og tilsvarende for mer fengslende parenteser.

Hvis du trenger å bruke parenteser, men ikke trenger å fange den verdien, kan du bruke ikke-fangende parenteser: (?: x ). I dette tilfellet blir det funnet et samsvar med x, men det huskes ikke.

La oss gå tilbake til gjeldende oppgave. Hvordan implementerer vi fangeparenteser? Ved å bruke JavaScript regexp-erstatningsmetoden! Vi sender "$1" som det andre argumentet. Det er viktig å bruke anførselstegn her.

funksjon removeCc(str)(
return str.replace(/()/g, "$1");
}


La oss se på koden igjen. Vi tar tak i den store bokstaven og erstatter den med den samme bokstaven. Inne i anførselstegnene setter du inn et mellomrom etterfulgt av variabelen $1 . Som et resultat får vi et mellomrom etter hver stor bokstav.

funksjon removeCc(str)(
return str.replace(/()/g, " $1");
}
removeCc("camelCase") // "camel Case"
removeCc("helloWorldItIsMe") // "hello World It Is Me"

Eksempel: fjerning av store bokstaver

Nå har vi en streng med en haug med unødvendige store bokstaver. Har du funnet ut hvordan du fjerner dem? Først må vi velge alle store bokstaver. Deretter søker vi etter et tegnsett ved å bruke den globale modifikatoren:

Vi bruker erstatningsmetoden igjen, men hvordan lager vi tegnet med små bokstaver denne gangen?

funksjon liten bokstav(str)(
return str.replace(//g, ???);
}


Hint: I replace()-metoden kan du spesifisere en funksjon som den andre parameteren.

Vi vil bruke en pilfunksjon for å unngå å fange opp verdien av det funnet. Når du bruker en funksjon i JavaScript regexp replace-metoden, vil funksjonen kalles opp etter at et samsvar er funnet, og resultatet av funksjonen brukes som erstatningsstreng. Enda bedre, hvis treffet er globalt og flere treff blir funnet, vil funksjonen bli kalt for hver treff som blir funnet.

funksjon liten bokstav(str)(
return str.replace(//g, (u) => u.toLowerCase());
}
lowerCase("camel case") // "camel case"
lowerCase("hei verden det er meg") // "hei verden det er meg"

Eksempel: konverter den første bokstaven til stor

capitalize("camel case") // => skal returnere "Camel case"

La oss bruke funksjonen i replace()-metoden igjen. Men denne gangen trenger vi bare å se etter det første tegnet i strengen. Husk at symbolet "^" brukes til dette.

La oss dvele ved "^"-symbolet et sekund. Husk eksempelet gitt tidligere:

console.log(/cat/.test("katten sier mjau"));
//Ikke sant

Når du legger til et "^"-tegn, returnerer ikke funksjonen lenger sant fordi ordet "katt" ikke er på begynnelsen av linjen.

Noen mennesker, når de står overfor et problem, tenker: "Å, jeg skal bruke vanlige uttrykk." Nå har de to problemer.
Jamie Zawinski

Yuan-Ma sa: «Det krever mye kraft å skjære tre på tvers av trefibrene. Det krever mye kode å programmere på tvers av problemstrukturen.
Master Yuan-Ma, "Book of Programming"

Programmeringsverktøy og -teknikker overlever og sprer seg på en kaotisk evolusjonær måte. Noen ganger er det ikke de vakre og briljante som overlever, men rett og slett de som fungerer godt nok på sitt felt – for eksempel hvis de integreres i en annen vellykket teknologi.

I dette kapittelet skal vi diskutere et slikt verktøy - regulære uttrykk. Dette er en måte å beskrive mønstre i strengdata. De lager et lite, frittstående språk som er inkludert i JavaScript og mange andre språk og verktøy.

De vanlige timeplanene er både veldig merkelige og ekstremt nyttige. Syntaksen deres er kryptisk og JavaScript-programmeringsgrensesnittet er klønete. Men dette kraftig verktøy for å utforske og behandle strenger. Når du forstår dem, vil du bli en mer effektiv programmerer.

Lage et regulært uttrykk

Vanlig – objekttype. Det kan opprettes ved å ringe RegExp-konstruktøren, eller ved å skrive nødvendig mal, omgitt av skråstreker.

Var re1 = new RegExp("abc"); var re2 = /abc/;

Begge disse regulære uttrykkene representerer det samme mønsteret: tegnet "a" etterfulgt av tegnet "b" etterfulgt av tegnet "c".

Hvis du bruker RegExp-konstruktøren, skrives mønsteret som vanlig streng, så alle reglene angående skråstreker gjelder.

Den andre oppføringen, der mønsteret er mellom skråstreker, behandler skråstrek annerledes. For det første, siden mønsteret ender med en skråstrek, må vi sette en skråstrek før skråstreken fremover som vi ønsker å inkludere i mønsteret vårt. I tillegg omvendt skråstrek som ikke er en del av spesielle karakterer type \n vil bli bevart (i stedet for ignorert, som i strenger), og vil endre betydningen av mønsteret. Noen tegn, som spørsmålstegnet eller pluss, har en spesiell betydning i regulære uttrykk, og skal du finne et slikt tegn, må det også innledes med en omvendt skråstrek.

Var eighteenPlus = /eighteen\+/;

For å vite hvilke tegn som må innledes med en skråstrek, må du lære en liste over alle spesialtegn i regulære uttrykk. Dette er foreløpig ikke mulig, så hvis du er i tvil, sett bare en skråstrek foran et tegn som ikke er en bokstav, tall eller mellomrom.

Ser etter treff

Gjengangere har flere metoder. Den enkleste er test. Hvis du sender den en streng, vil den returnere en boolsk verdi som indikerer om strengen inneholder en forekomst av det gitte mønsteret.

Console.log(/abc/.test("abcde")); // → true console.log(/abc/.test("abxde")); // → usant

En vanlig sekvens som kun består av ikke-spesialtegn er ganske enkelt en sekvens av disse tegnene. Hvis abc er hvor som helst i linjen vi tester (ikke bare i begynnelsen), vil testen returnere sann.

Ser etter et sett med karakterer

Du kan også finne ut om en streng inneholder abc ved å bruke indexOf. Vanlige mønstre lar deg gå lenger og skape mer komplekse mønstre.

La oss si at vi må finne et hvilket som helst tall. Når vi setter et sett med tegn i hakeparenteser i regulært uttrykk, betyr det at den delen av uttrykket samsvarer med alle tegnene i parentesene.

Begge uttrykkene er i linjer som inneholder et tall.

Console.log(//.test("i 1992")); // → true console.log(//.test("i 1992")); // → sant

I hakeparenteser brukes en bindestrek mellom to tegn for å spesifisere en rekke tegn, der sekvensen er spesifisert av Unicode-kodingen. Tegnene fra 0 til 9 er der bare på rad (koder fra 48 til 57), så det fanger dem alle og matcher et hvilket som helst tall.

Flere tegngrupper har egne innebygde forkortelser.

\d Hvilket som helst tall
\w Alfanumerisk tegn
\s Mellomrom (mellomrom, tabulator, ny linje osv.)
\D ikke et tall
\W er ikke et alfanumerisk tegn
\S er ikke et mellomrom
. alle tegn unntatt linjeskift

Dermed kan du angi dato- og klokkeslettformat som 01/30/2003 15:20 med følgende uttrykk:

Var dateTime = /\d\d-\d\d-\d\d\d\d \d\d:\d\d/; console.log(dateTime.test("30-01-2003 15:20")); // → true console.log(dateTime.test("30-Jan-2003 15:20")); // → usant

Ser forferdelig ut, ikke sant? Det er for mange skråstreker, noe som gjør mønsteret vanskelig å forstå. Vi forbedrer det litt senere.

Omvendt skråstrek kan også brukes i firkantede parenteser. For eksempel betyr [\d.] et hvilket som helst tall eller punktum. Legg merke til at perioden innenfor hakeparentesene mister sin spesielle betydning og blir rett og slett et punktum. Det samme gjelder andre spesialtegn, for eksempel +.

Du kan invertere et sett med tegn - det vil si at du trenger å finne et hvilket som helst tegn bortsett fra de som er i settet - ved å plassere et ^-tegn umiddelbart etter den åpne hakeparentesen.

Var notBinary = /[^01]/; console.log(notBinary.test("1100100010100110")); // → falsk console.log(notBinary.test("1100100010200110")); // → sant

Repeterende deler av malen

Vi vet hvordan vi finner ett tall. Hva om vi trenger å finne hele tallet - en sekvens av ett eller flere siffer?

Hvis du setter et +-tegn etter noe i den vanlige rekkefølgen, vil dette bety at dette elementet kan gjentas mer enn én gang. /\d+/ betyr ett eller flere sifre.

Console.log(/"\d+"/.test(""123"")); // → true console.log(/"\d+"/.test("""")); // → false console.log(/"\d*"/.test(""123"")); // → true console.log(/"\d*"/.test("""")); // → sant

Stjernen * har nesten samme betydning, men den lar mønsteret forekomme null ganger. Hvis noe blir etterfulgt av en stjerne, hindrer det aldri mønsteret fra å være i linjen - det vises bare der null ganger.

Et spørsmålstegn gjør en del av mønsteret valgfritt, noe som betyr at det kan forekomme null eller én gang. I følgende eksempel kan tegnet u vises, men mønsteret samsvarer selv når det ikke gjør det.

Var nabo = /neighbou?r/; console.log(neighbor.test("nabo")); // → true console.log(neighbor.test("nabo")); // → sant

For å spesifisere nøyaktig antall ganger et mønster må forekomme, bruk tannregulering. (4) etter et element betyr at det må vises 4 ganger på linjen. Du kan også angi et gap: (2,4) betyr at elementet må forekomme minst 2 og ikke mer enn 4 ganger.

En annen versjon av dato- og klokkeslettformatet, der dager, måneder og timer med ett eller to sifre er tillatt. Og den er også litt mer lesbar.

Var datoTid = /\d(1,2)-\d(1,2)-\d(4) \d(1,2):\d(2)/; console.log(dateTime.test("30-1-2003 8:45")); // → sant

Du kan bruke åpne mellomrom ved å utelate ett av tallene. (,5,) betyr at mønsteret kan forekomme fra null til fem ganger, og (5,) betyr fra fem eller flere.

Gruppering av underuttrykk

For å bruke * eller + operatorene på flere elementer samtidig, kan du bruke parenteser. Den delen av det regulære uttrykket i parentes regnes som ett element fra operatørenes synspunkt.

Var cartoonCrying = /boo+(hoo+)+/i; console.log(cartoonCrying.test("Boohoooohoohoooo")); // → sant

Første og andre pluss gjelder kun for andre o'er i boo og hoo. Det tredje + refererer til hele gruppen (hoo+), som finner en eller flere slike sekvenser.

Bokstaven i på slutten av uttrykket gjør det regulære uttrykket ufølsomt for store og små bokstaver - slik at B stemmer overens med b.

Kamper og grupper

Testmetoden er den enkleste metoden for å sjekke regulære uttrykk. Den forteller deg bare om en match ble funnet eller ikke. Gjengangere har også en exec-metode, som vil returnere null hvis ingenting ble funnet, og ellers returnere et objekt med informasjon om kampen.

Var match = /\d+/.exec("en to 100"); console.log(match); // → ["100"] console.log(match.index); // → 8

Objektet som returneres av exec har en indeksegenskap, som inneholder nummeret på tegnet som samsvaret skjedde fra. Generelt ser objektet ut som en rekke strenger, der det første elementet er strengen som ble sjekket for samsvar. I vårt eksempel vil dette være tallrekkefølgen vi lette etter.

Strenger har en matchmetode som fungerer omtrent på samme måte.

Console.log("en to 100".match(/\d+/)); // → ["100"]

Når et regulært uttrykk inneholder underuttrykk gruppert i parentes, vil teksten som samsvarer med disse gruppene også vises i matrisen. Det første elementet er alltid en komplett match. Den andre er delen som samsvarte med den første gruppen (den hvis parentes oppstod først), deretter den andre gruppen, og så videre.

Var quotedText = /"([^"]*)"/; console.log(quotedText.exec("hun sa "hei"")); // → [""hei"", "hei"]

Når en gruppe ikke blir funnet i det hele tatt (for eksempel hvis den etterfølges av et spørsmålstegn), er dens posisjon i matrisen udefinert. Hvis en gruppe matcher flere ganger, vil bare den siste kampen være i arrayet.

Console.log(/bad(ly)?/.exec("bad")); // → ["dårlig", udefinert] console.log(/(\d)+/.exec("123")); // → ["123", "3"]

Grupper er nyttige for å hente deler av strenger. Hvis vi ikke bare vil sjekke om en streng har en dato, men trekke den ut og lage et objekt som representerer datoen, kan vi sette tallsekvensene i parentes og velge datoen fra resultatet av exec.

Men først, en liten digresjon der vi lærer den foretrukne måten å lagre dato og klokkeslett på i JavaScript.

Datotype

JavaScript har standard type objekt for datoer - eller rettere sagt, øyeblikk i tid. Det heter Date. Hvis du bare oppretter et datoobjekt via ny får du dagens dato og tid.

Console.log(ny dato()); // → Søn 9. nov. 2014 00:07:57 GMT+0300 (CET)

Du kan også lage et objekt som inneholder en gitt tid

Console.log(ny dato(2015, 9, 21)); // → ons 21. okt. 2015 00:00:00 GMT+0300 (CET) console.log(ny dato(2009, 11, 9, 12, 59, 59, 999)); // → ons 09. desember 2009 12:59:59 GMT+0300 (CET)

JavaScript bruker en konvensjon der månedstall starter med en null og dagstall starter med en. Dette er dumt og latterlig. Vær forsiktig.

De fire siste argumentene (timer, minutter, sekunder og millisekunder) er valgfrie og er satt til null hvis de mangler.

Tidsstempler lagres som antall millisekunder som har gått siden begynnelsen av 1970. For tider før 1970, bruk negative tall(dette er på grunn av Unix-tidskonvensjonen som ble opprettet rundt den tiden). Datoobjektets getTime-metode returnerer dette tallet. Den er naturlig stor.
console.log(ny dato(2013, 11, 19).getTime()); // → 1387407600000 console.log(ny dato(1387407600000)); // → tor 19. desember 2013 00:00:00 GMT+0100 (CET)

Hvis du gir Dato-konstruktøren ett argument, behandles det som dette antallet millisekunder. Du kan få gjeldende millisekundverdi ved å opprette et Date-objekt og kalle opp getTime-metoden, eller ved å kalle Date.now-funksjonen.

Date-objektet har metodene getFullYear, getMonth, getDate, getHours, getMinutes og getSeconds for å hente komponentene. Det er også en getYear-metode som returnerer en ganske ubrukelig tosifret kode som 93 eller 14.

Ved å sette de relevante delene av malen i parentes, kan vi lage et datoobjekt direkte fra strengen.

Funksjon findDate(string) ( var dateTime = /(\d(1,2))-(\d(1,2))-(\d(4))/; var match = dateTime.exec(string); return new Date(Number(match), Number(match) - 1, Number(match)); ) console.log(findDate("30-1-2003")); // → Tor 30. jan 2003 00:00:00 GMT+0100 (CET)

Ord- og linjegrenser

Dessverre vil findDate like gjerne trekke ut den meningsløse datoen 00-1-3000 fra strengen "100-1-30000". Matchen kan forekomme hvor som helst i strengen, så i dette tilfellet det vil ganske enkelt starte fra det andre tegnet og slutte på det nest siste.

Hvis vi må tvinge treffet til å ta hele strengen, bruker vi taggene ^ og $. ^ samsvarer med begynnelsen av linjen, og $ samsvarer med slutten. Derfor samsvarer /^\d+$/ en streng som inneholder bare ett eller flere sifre, /^!/ samsvarer med en streng som starter med et utropstegn, og /x^/ samsvarer ikke med noen streng (det kan ikke være en x).

Hvis vi derimot bare vil forsikre oss om at datoen starter og slutter på en ordgrense, bruker vi \b-merket. En ordgrense kan være begynnelsen eller slutten av en linje, eller et hvilket som helst sted i en linje der det er et alfanumerisk tegn \w på den ene siden og et ikke-alfanumerisk tegn på den andre.

Console.log(/cat/.test("sammenknytte")); // → true console.log(/\bcat\b/.test("sammenknytte")); // → usant

Merk at grenseetiketten ikke er et symbol. Det er ganske enkelt en begrensning, noe som betyr at et samsvar bare oppstår hvis en bestemt betingelse er oppfylt.

Maler med valg

La oss si at du må finne ut om teksten ikke bare inneholder et tall, men et tall etterfulgt av gris, ku eller kylling i entall eller flertall.

Det ville være mulig å skrive tre regulære uttrykk og sjekke dem ett etter ett, men det er en bedre måte. Symbol | betegner et valg mellom mønstrene til venstre og til høyre for den. Og vi kan si følgende:

Var animalCount = /\b\d+ (gris|ku|kylling)s?\b/; console.log(animalCount.test("15 griser")); // → true console.log(animalCount.test("15 grisekyllinger")); // → usant

Parenteser avgrenser delen av mønsteret som | brukes på, og mange slike operatorer kan plasseres etter hverandre for å indikere et valg mellom mer enn to alternativer.

Søkemotor

Regelmessige uttrykk kan betraktes som flytskjemaer. Følgende diagram beskriver et nylig husdyreksempel.

Et uttrykk samsvarer med en streng hvis det er mulig å finne en sti fra venstre side av diagrammet til høyre. Vi husker gjeldende posisjon i linjen, og hver gang vi går gjennom rektangelet, sjekker vi at delen av linjen rett etter posisjonen vår i den samsvarer med innholdet i rektangelet.

Dette betyr at det å se etter samsvar med vår vanlige karakter i strengen "de 3 griser" når du går gjennom flytskjemaet ser slik ut:

Ved posisjon 4 er det en ordgrense, og vi passerer det første rektangelet
- fra 4. posisjon finner vi tallet og går gjennom det andre rektangelet
- ved posisjon 5 lukkes den ene banen tilbake foran det andre rektangelet, og den andre går videre til rektangelet med et mellomrom. Vi har et mellomrom, ikke et tall, og vi velger den andre veien.
- nå er vi på posisjon 6, begynnelsen av "griser", og ved trippel forgrening av stiene. Det er ingen "ku" eller "kylling" i linjen, men det er "gris", så vi velger denne veien.
- ved posisjon 9 etter trippelgaffelen, omgår den ene banen "s" og går til grenserektangelet for det siste ordet, og den andre går gjennom "s". Vi har en "s" så vi drar dit.
- ved posisjon 10 er vi på slutten av linjen, og bare ordet grense kan matche. Enden av linjen regnes som grensen, og vi passerer gjennom det siste rektangelet. Og nå har vi funnet malen vår.

I utgangspunktet er måten regulære uttrykk fungerer på at algoritmen starter på begynnelsen av strengen og prøver å finne en match der. I vårt tilfelle er det en ordgrense, så den passerer det første rektangelet - men det er ikke noe tall der, så det snubler over det andre rektangelet. Så flytter den seg til det andre tegnet i strengen, og prøver å finne et samsvar der... Og så videre til det finner et samsvar eller kommer til slutten av strengen, i så fall blir det ikke funnet noe samsvar.

Tilbakeslag

Det regulære uttrykket /\b(+b|\d+|[\da-f]h)\b/ samsvarer med enten et binært tall etterfulgt av en b, et desimaltall uten suffiks, eller et heksadesimalt tall (tallene 0 til 9 eller symbolene fra a til h), etterfulgt av h. Relevant diagram:

Når du søker etter et samsvar, kan det hende at algoritmen tar den øverste banen (binært tall), selv om det ikke er et slikt tall i strengen. Hvis det for eksempel er en linje "103", er det klart at først etter å ha nådd tallet 3, vil algoritmen forstå at den er på feil vei. Generelt samsvarer linjen med den vanlige sekvensen, bare ikke i denne tråden.

Så ruller algoritmen tilbake. Ved en gaffel husker den gjeldende posisjon (i vårt tilfelle er dette begynnelsen av linjen, like etter ordet grense) slik at du kan gå tilbake og prøve en annen vei hvis den valgte ikke fungerer. For strengen "103", etter å ha møtt en treer, vil den gå tilbake og prøve å gå gjennom desimalbanen. Dette vil fungere, så en match vil bli funnet.

Algoritmen stopper så snart den finner en fullstendig match. Dette betyr at selv om flere alternativer kan være passende, brukes kun ett av dem (i den rekkefølgen de vises i den vanlige rekkefølgen).

Tilbakesporing skjer når du bruker repetisjonsoperatorer som + og *. Hvis du søker etter /^.*x/ i strengen "abcxe", vil regex-delen.* prøve å konsumere hele strengen. Algoritmen vil da innse at den også trenger "x". Siden det ikke er noen "x" etter slutten av strengen, vil algoritmen prøve å se etter samsvar ved å flytte ett tegn tilbake. Etter abcx er det heller ingen x, så ruller den tilbake igjen, denne gangen til understrengen abc. Og etter linjen finner den x og rapporterer en vellykket match, i posisjonene 0 til 4.

Du kan skrive en vanlig rutine som vil føre til flere tilbakeføringer. Dette problemet oppstår når mønsteret kan matche inndataene flere ganger. forskjellige måter. For eksempel hvis vi gjør en feil når vi skriver et regulært uttrykk for binære tall, kan vi ved et uhell skrive noe som /(+)+b/.

Hvis algoritmen skulle se etter et slikt mønster i en lang streng med 0-er og 1-ere som ikke hadde en "b" på slutten, ville den først gå gjennom den indre sløyfen til den gikk tom for sifre. Da vil han legge merke til at det ikke er noen "b" på slutten, han vil rulle tilbake en posisjon, gå gjennom den ytre løkken, gi opp igjen, prøve å rulle tilbake til en annen posisjon langs den indre sløyfen... Og han vil fortsette å søke på denne måten ved å bruke begge løkkene. Det vil si at mengden arbeid med hvert tegn på linjen vil dobles. Selv for flere dusin karakterer vil det ta veldig lang tid å finne en match.

erstatte metoden

Strenger har en erstatningsmetode som kan erstatte en del av en streng med en annen streng.

Console.log("pappa".replace("p", "m")); // → kart

Det første argumentet kan også være et regulært uttrykk, i så fall erstattes den første forekomsten av det regulære uttrykket på linjen. Når alternativet "g" (globalt) legges til det regulære uttrykket, erstattes alle forekomster, ikke bare den første

Console.log("Borobudur".replace(//, "a")); // → Barobudur console.log("Borobudur".replace(//g, "a")); // → Barabadar

Det ville være fornuftig å sende alternativet "erstatt alle" gjennom et eget argument, eller gjennom en separat metode som replaceAll. Men dessverre overføres alternativet gjennom det vanlige systemet selv.

Den fulle kraften til regulære uttrykk avsløres når vi bruker lenker til grupper som finnes i en streng, spesifisert i det regulære uttrykket. For eksempel har vi en linje som inneholder personers navn, ett navn per linje, i formatet "Etternavn, Fornavn". Hvis vi trenger å bytte dem og fjerne kommaet for å få «Fornavn Etternavn», skriver vi følgende:

Console.log("Hopper, Grace\nMcCarthy, John\nRitchie, Dennis" .replace(/([\w ]+), ([\w ]+)/g, "$2 $1")); // → Grace Hopper // John McCarthy // Dennis Ritchie

$1 og $2 i erstatningslinjen refererer til grupper av tegn i parentes. $1 erstattes med teksten som samsvarer med den første gruppen, $2 med den andre gruppen, og så videre, opptil $9. Hele samsvaret er inneholdt i $&-variabelen.

Du kan også sende en funksjon som det andre argumentet. For hver erstatning vil det bli kalt en funksjon hvis argumenter vil være de funnet gruppene (og hele den matchende delen av linjen), og resultatet vil bli satt inn i en ny linje.

Enkelt eksempel:

Var s = "cia og fbi"; console.log(s.replace(/\b(fbi|cia)\b/g, function(str) (retur str.toUpperCase(); ))); // → CIA og FBI

Her er en mer interessant:

Var lager = "1 sitron, 2 kål og 101 egg"; function minusOne(match, amount, unit) ( amount = Number(amount) - 1; if (amount == 1) // bare én igjen, fjern "s" på slutten unit = unit.slice(0, unit. lengde - 1); else if (beløp == 0) beløp = "nei"; returbeløp + " " + enhet; ) console.log(stock.replace(/(\d+) (\w+)/g, minusOne) ); // → ingen sitron, 1 kål og 100 egg

Koden tar en streng, finner alle forekomster av tall etterfulgt av et ord, og returnerer en streng med hvert tall redusert med ett.

Gruppen (\d+) går inn i beløpsargumentet, og (\w+) går inn i enhetsargumentet. Funksjonen konverterer beløp til et tall - og dette fungerer alltid, fordi vårt mønster er \d+. Og gjør deretter endringer i ordet, i tilfelle det bare er 1 element igjen.

Grådighet

Det er enkelt å bruke erstatning for å skrive en funksjon som fjerner alle kommentarer fra JavaScript-kode. Her er første forsøk:

Funksjon stripComments(code) ( return code.replace(/\/\/.*|\/\*[^]*\*\//g, ""); ) console.log(stripComments("1 + /* 2 */3")); // → 1 + 3 console.log(stripComments("x = 10;// ti!")); // → x = 10; console.log(stripComments("1 /* a */+/* b */ 1")); // → 1 1

Delen før "eller"-operatoren samsvarer med to skråstreker etterfulgt av et hvilket som helst antall tegn unntatt nylinjer. Den delen som fjerner kommentarer med flere linjer er mer kompleks. Vi bruker [^], dvs. et hvilket som helst tegn som ikke er tomt som en måte å finne noen tegn. Vi kan ikke bruke en periode fordi blokkkommentarer fortsetter ny linje, og nylinjetegnet samsvarer ikke med punktum.

Men resultatet fra forrige eksempel er feil. Hvorfor?

[^]*-delen vil først prøve å fange så mange karakterer den kan. Hvis den neste delen av den vanlige sekvensen på grunn av dette ikke finner en match, vil den rulle tilbake ett tegn og prøve på nytt. I eksemplet prøver algoritmen å ta hele linjen, og ruller deretter tilbake. Etter å ha rullet tilbake 4 tegn, vil han finne */ i linjen - og dette er ikke det vi ønsket. Vi ønsket å ta bare én kommentar, og ikke gå til slutten av linjen og finne den siste kommentaren.

På grunn av dette sier vi at repetisjonsoperatorene (+, *, ?, og ()) er grådige, noe som betyr at de først griper så mye de kan og deretter går tilbake. Hvis du stiller et spørsmål etter en operator som dette (+?, *?, ??, ()?), vil de bli til ikke-grådige, og begynne å finne de minste mulige forekomstene.

Og det er det vi trenger. Ved å tvinge stjernen til å finne samsvar med minst mulig antall tegn på en linje, bruker vi bare én blokk med kommentarer, og ikke mer.

Funksjon stripComments(code) ( return code.replace(/\/\/.*|\/\*[^]*?\*\//g, ""); ) console.log(stripComments("1 /* a */+/* b */ 1")); // → 1 + 1

Mange feil oppstår ved bruk av grådige operatorer i stedet for ikke-grådige. Når du bruker repetisjonsoperatøren, må du alltid vurdere den ikke-grådige operatøren først.

Dynamisk oppretting av RegExp-objekter

I noen tilfeller er det nøyaktige mønsteret ukjent på tidspunktet koden skrives. Du må for eksempel se etter brukerens navn i teksten, og legge det ved understrek. Siden du først kjenner navnet etter å ha kjørt programmet, kan du ikke bruke skråstreknotasjon.

Men du kan konstruere strengen og bruke RegExp-konstruktøren. Her er et eksempel:

Var navn = "harry"; var text = "Og Harry har et arr i pannen."; var regexp = new RegExp("\\b(" + navn + ")\\b", "gi"); console.log(text.replace(regexp, "_$1_")); // → Og _Harry_ har et arr i pannen.

Når vi lager ordgrenser, må vi bruke doble skråstreker fordi vi skriver dem på en vanlig linje, og ikke i en vanlig rekkefølge med skråstreker fremover. Det andre argumentet til RegExp inneholder alternativer for regulære uttrykk - i vårt tilfelle "gi", dvs. global og skiller mellom store og små bokstaver.

Men hva om navnet er "dea+hlrd" (hvis brukeren vår er en kulhatzker)? Som et resultat vil vi få et meningsløst regulært uttrykk som ikke finner treff i strengen.

Vi kan legge til omvendte skråstreker før alle karakterer vi ikke liker. Vi kan ikke legge til omvendte skråstreker før bokstaver fordi \b eller \n er spesialtegn. Men du kan legge til skråstreker før alle ikke-alfanumeriske tegn uten problemer.

Var navn = "dea+hlrd"; var text = "Denne dea+hlrd irriterer alle."; var escaped = name.replace(/[^\w\s]/g, "\\$&"); var regexp = new RegExp("\\b(" + escaped + ")\\b", "gi"); console.log(text.replace(regexp, "_$1_")); // → Dette _dea+hlrd_ irriterte alle.

søkemetode

indexOf-metoden kan ikke brukes med regulære uttrykk. Men det er en søkemetode som bare forventer regulært uttrykk. Som indexOf, returnerer den indeksen for den første forekomsten, eller -1 hvis ingen forekommer.

Console.log(" word".search(/\S/)); // → 2 console.log(" ".search(/\S/)); // → -1

Dessverre er det ingen måte å fortelle metoden om å se etter en kamp som starter med en spesifikk forskyvning (slik du kan gjøre med indexOf). Det ville være nyttig.

lastIndex-egenskapen

Exec-metoden fungerer heller ikke praktisk måte begynne å søke fra en gitt posisjon i strengen. Men det gir en upraktisk måte.

Et regulært uttrykk har egenskaper. En av dem er kilde, som inneholder en streng. En annen er lastIndex, som kontrollerer, under visse forhold, hvor neste søk etter forekomster vil begynne.

Disse betingelsene inkluderer at det globale alternativet g må være til stede, og at søket må gjøres ved hjelp av exec-metoden. En mer fornuftig løsning ville være å ganske enkelt tillate at et ekstra argument sendes til exec, men rimelighet er ikke en grunnleggende funksjon i JavaScript-regex-grensesnittet.

Var-mønster = /y/g; pattern.lastIndex = 3; var match = pattern.exec("xyzzy"); console.log(match.index); // → 4 console.log(pattern.lastIndex); // → 5

Hvis søket var vellykket, oppdaterer exec-kallet lastIndex-egenskapen til å peke på posisjonen etter den funnet forekomsten. Hvis det ikke var suksess, settes lastIndex til null - akkurat som lastIndex for det nyopprettede objektet.

Når du bruker en global regulær variabel og flere exec-kall, kan disse automatiske lastIndex-oppdateringene forårsake problemer. Din vanlige server kan begynne å søke fra posisjonen til venstre fra forrige samtale.

Var-siffer = /\d/g; console.log(digit.exec("her er det: 1")); // → ["1"] console.log(digit.exec("og nå: 1")); // → null

En annen interessant effekt av g-alternativet er at det endrer hvordan matchmetoden fungerer. Når den kalles med dette alternativet, i stedet for å returnere en matrise som ligner resultatet av exec, finner den alle forekomster av mønsteret i strengen og returnerer en matrise med de funnet delstrengene.

Console.log("Banana".match(/an/g)); // → ["en", "en"]

Så vær forsiktig med globale regulære variabler. De tilfellene der de er nødvendige - erstatt samtaler eller steder der du spesifikt bruker lastIndex - er sannsynligvis alle tilfellene de bør brukes i.

Forekomst sykluser

En typisk oppgave er å iterere gjennom alle forekomster av et mønster i en streng, slik at det kan få tilgang til matchobjektet i løkken ved hjelp av lastIndex og exec.

Var input = "En linje med 3 tall i... 42 og 88."; var nummer = /\b(\d+)\b/g; var match; while (match = number.exec(input)) console.log("Funnet", match, " på ", match.index); // → Funnet 3 x 14 // Funnet 42 x 33 // Funnet 88 x 40

Den utnytter det faktum at verdien av oppdraget er verdien som tildeles. Bruker match = re.exec(input) som en betingelse i mens loop, søker vi i begynnelsen av hver iterasjon, lagrer resultatet i en variabel og avslutter loopen når alle treff er funnet.

Parsing INI-filer

For å avslutte kapitlet, la oss se på et problem ved å bruke regulære uttrykk. Tenk deg at vi skriver et program som samler informasjon om fiendene våre via Internett. automatisk modus. (Vi vil ikke skrive hele programmet, bare den delen som leser innstillingsfilen. Beklager.) Filen ser slik ut:

Searchengine=http://www.google.com/search?q=$1 spitefulness=9.7 ; et semikolon er plassert før kommentarer; hver seksjon refererer til et annet fiende fullt navn=Larry Doe type=barnehage okse nettsted=http://www.geocities.com/CapeCanaveral/11451 fullname=Gargamel type=evil wizard outputdir=/home/marijn/enemies/gargamel

Det nøyaktige filformatet (som er ganske mye brukt, og vanligvis kalles INI) er som følger:

Tomme linjer og linjer som begynner med semikolon ignoreres
- linjer omsluttet av firkantede parenteser begynner en ny seksjon
- linjer som inneholder en alfanumerisk identifikator etterfulgt av = legg til en innstilling i denne delen

Alt annet er feil data.

Vår oppgave er å konvertere en slik streng til en rekke objekter, hver med en navneegenskap og en rekke innstillinger. Det trengs ett objekt for hver seksjon, og ett til for globale innstillingerøverst i filen.

Siden filen må analyseres linje for linje, er det en god idé å starte med å dele opp filen i linjer. For å gjøre dette brukte vi string.split("\n") i kapittel 6. Noen operativsystemer bruker ikke ett \n-tegn for linjeskift, men to - \r\n. Siden split-metoden tar regulære uttrykk som et argument, kan vi dele linjer ved å bruke uttrykket /\r?\n/, slik at både enkelt \n og \r\n mellom linjer.

Funksjonen parseINI(streng) ( // La oss starte med et objekt som inneholder toppnivåinnstillinger var currentSection = (navn: null, felt: ); var categories = ; string.split(/\r?\n/).forEach(function (linje ) ( var match; if (/^\s*(;.*)?$/.test(line)) ( return; ) else if (match = line.match(/^\[(.*)\ ]$ /)) ( currentSection = (navn: match, felter: ); categories.push(currentSection); ) else if (match = line.match(/^(\w+)=(.*)$/)) ( currentSection. fields.push((navn: match, verdi: match)); ) else ( throw new Error("Linjen "" + linje + "" inneholder ugyldige data."); ) )); returkategorier; )

Koden går gjennom alle linjene, og oppdaterer det gjeldende seksjonsobjektet "current section". Først sjekker den om linjen kan ignoreres ved å bruke det regulære uttrykket /^\s*(;.*)?$/. Kan du forestille deg hvordan dette fungerer? Delen mellom parentesene stemmer med kommentarene, ikke sant? gjør det slik at det vanlige tegnet også vil matche linjer som kun består av mellomrom.

Hvis linjen ikke er en kommentar, sjekker koden for å se om den starter en ny seksjon. Hvis ja, opprettes et nytt objekt for gjeldende seksjon, som påfølgende innstillinger legges til.

Den siste meningsfulle muligheten er at strengen er en normal innstilling, i så fall legges den til det gjeldende objektet.

Hvis ingen av alternativene fungerer, gir funksjonen en feil.

Legg merke til hvordan hyppig bruk av ^ og $ sikrer at uttrykket samsvarer med hele strengen i stedet for bare en del av den. Hvis du ikke bruker dem, vil koden generelt fungere, men vil noen ganger gi merkelige resultater og feilen vil være vanskelig å spore opp.

If (match = string.match(...))-konstruksjonen ligner på trikset med å bruke tilordning som en betingelse i en while-løkke. Ofte vet du ikke at match-kallet vil lykkes, så du kan bare få tilgang til resultatobjektet i en if-blokk som sjekker etter det. For ikke å bryte den vakre kjeden av if-sjekker, tildeler vi søkeresultatet til en variabel og bruker umiddelbart denne tilordningen som en sjekk.

Internasjonale symboler

På grunn av den i utgangspunktet enkle implementeringen av språket, og den påfølgende fikseringen av en slik implementering "i granitt", er vanlige JavaScript-uttrykk dumme med tegn som ikke finnes på engelsk. For eksempel kan "bokstav"-tegnet, sett fra JavaScript-regulære uttrykk, være en av de 26 bokstavene i det engelske alfabetet, og av en eller annen grunn også et understrek. Bokstaver som é eller β, som tydeligvis er bokstaver, samsvarer ikke med \w (og vil samsvare med \W, som er en ikke-bokstav).

I en merkelig tilfeldighet samsvarer historisk \s (mellomrom) alle tegn som anses som mellomrom i Unicode, inkludert ting som ikke-brytende plass eller mongolsk vokalseparator.

Noen regex-implementeringer på andre språk har spesiell syntaks for å søke etter spesielle kategorier av Unicode-tegn, for eksempel "all caps", "all interpunctuation" eller "control characters". Det er planer om å legge til slike kategorier i JavaScript, men de vil sannsynligvis ikke bli implementert snart.

Bunnlinjen

Regelmessige er objekter som representerer søkemønstre i strenger. De bruker sin egen syntaks for å uttrykke disse mønstrene.

/abc/ Tegnsekvens
// Ethvert tegn fra listen
/[^abc]/ Ethvert tegn unntatt tegn fra listen
// Et hvilket som helst tegn fra intervallet
/x+/ En eller flere forekomster av mønsteret x
/x+?/ En eller flere forekomster, ikke-grådig
/x*/ Null eller flere forekomster
/x?/ Null eller én forekomst
/x(2,4)/ Fra to til fire forekomster
/(abc)/ Gruppe
/a|b|c/ Hvilket som helst av flere mønstre
/\d/ Hvilket som helst tall
/\w/ Ethvert alfanumerisk tegn ("bokstav")
/\s/ Ethvert mellomromstegn
/./ Alle tegn unntatt nylinjer
/\b/ Ordgrense
/^/ Start av linje
/$/ Slutt på linjen

Regex har en testmetode for å sjekke om mønsteret er i strengen. Det er en exec-metode som returnerer en matrise som inneholder alle gruppene som er funnet. Matrisen har en indeksegenskap, som inneholder nummeret til tegnet som samsvaret skjedde fra.

Strenger har en matchmetode for å matche mønstre, og en søkemetode som bare returnerer startposisjonen til forekomsten. Erstatningsmetoden kan erstatte forekomster av et mønster med en annen streng. I tillegg kan du sende en funksjon for å erstatte som vil bygge en erstatningslinje basert på malen og funnet grupper.

Vanlige tegn har innstillinger som er skrevet etter den avsluttende skråstreken. Alternativet i gjør det regulære uttrykket ufølsomt for store og små bokstaver, og alternativet g gjør det globalt, noe som blant annet gjør at erstatningsmetoden erstatter alle forekomster som er funnet, ikke bare den første.

RegExp-konstruktøren kan brukes til å lage regulære uttrykk fra strenger.

Regulatorer er et skarpt instrument med et ubehagelig håndtak. De forenkler noen oppgaver i stor grad, og kan bli uhåndterlige når man løser andre, komplekse problemer. En del av å lære å bruke regexes er å kunne motstå fristelsen til å fylle dem med en oppgave de ikke er ment for.

Øvelser

Når du løser problemer, vil du uunngåelig møte uforståelige tilfeller, og du kan noen ganger fortvile når du ser den uforutsigbare oppførselen til noen regulære uttrykk. Noen ganger hjelper det å studere oppførselen til en vanlig motor gjennom en nettjeneste som debuggex.com, hvor du kan se visualiseringen og sammenligne den med ønsket effekt.
Vanlig golf
"Golf" i kode er et spill hvor du trenger å uttrykke gitt program minimum antall tegn. Vanlig golf er en praktisk øvelse i å skrive minst mulig gjengangere for å finne et gitt mønster, og bare det.

For hver av underlinjene skriver du et regulært uttrykk for å sjekke plasseringen i linjen. Den vanlige motoren skal bare finne disse spesifiserte understrengene. Ikke bekymre deg for ordgrenser med mindre det er spesifikt nevnt. Når du har et fungerende vanlig mønster, prøv å redusere det.

Bil og katt
- pop og prop
- ilder, ferge og ferrari
- Ethvert ord som slutter på ious
- Et mellomrom etterfulgt av et punktum, komma, kolon eller semikolon.
- Et ord lengre enn seks bokstaver
- Ord uten bokstaver e

// Skriv inn dine vanlige uttrykk verify(/.../, ["min bil", "bad cats"], ["camper", "high art"]); verify(/.../, ["popkultur", "gal rekvisitter"], ["plopp"]); verify(/.../, ["ilder", "ferge", "ferrari"], ["ferrum", "overføring A"]); verify(/.../, ["hvor deilig", "romslig rom"], ["ødeleggende", "bevissthet"]); verify(/.../, ["dårlig tegnsetting ."], ["escape the dot"]); verify(/.../, ["hottenottententen"], ["no", "hottentottententen"]); verify(/.../, ["rød nebbdyr", "wobbling nest"], ["jordseng", "lærende ape"]); function verify(regexp, yes, no) ( // Ignorer uferdige øvelser if (regexp.source == "...") return; yes.forEach(function(s) (if (!regexp.test(s)) console .log("Ikke funnet "" + s + """); )); no.forEach(funksjon(er) (if (regexp.test(s)) console.log("Uventet forekomst av "" + s + " ""); )); )

Sitater i tekst
La oss si at du skrev en historie og brukte enkeltsitater for å indikere dialog. Nå vil du erstatte dialoganførselstegnene med doble anførselstegn, og la de enkle anførselstegnene stå i forkortelser for ord som ikke er det.

Kom opp med et mønster som skiller mellom disse to bruken av anførselstegn, og skriv en oppfordring til erstatningsmetoden som gjør erstatningen.

Tall igjen
Sekvenser av tall kan bli funnet med et enkelt regulært uttrykk /\d+/.

Skriv et uttrykk som bare finner tall skrevet i JavaScript-stil. Den skal støtte et mulig minus eller pluss før tallet, et desimaltegn og vitenskapelig notasjon 5e-3 eller 1E10 - igjen med mulig pluss eller minus. Vær også oppmerksom på at det ikke nødvendigvis er tall før eller etter prikken, men tallet kan ikke bestå av en enkelt prikk. Det vil si at .5 eller 5. er gyldige tall, men en prikk i seg selv er det ikke.

// Skriv inn den vanlige sekvensen her. var nummer = /^...$/; // Tester: ["1", "-1", "+15", "1.55", ".5", "5.", "1.3e2", "1E-4", "1e+12"] .forEach(function(s) ( if (!number.test(s)) console.log("Fant ikke "" + s + """); )); ["1a", "+-1", "1.2.3", "1+1", "1e4.5", ".5.", "1f5", "."].forHver(funksjon(er) ( if (number.test(s)) console.log("Feilaktig akseptert "" + s + """); ));

Regex eller regulære uttrykk er skremmende for nybegynnere, men avgjørende for enhver programmerer. La oss forstå regulære uttrykk ved å bruke 5 enkle eksempler med JavaScript.

Hvis du har et problem og du skal løse det med regulære uttrykk, har du nå to problemer. Det er et ordtak. Vanlige uttrykk som finnes i kode forårsaker noen ganger frykt og hat hos mennesker som ikke er kjent med dem.

Men faktisk er ethvert regex bare et maluttrykk som kan løse problemet med en hel funksjon på én linje. Men for å bygge et regulært uttrykk, må du ta hensyn til et sett med strenge regler som en nybegynner kan bli forvirret og gjøre feil i.

Matchende karakterer

De mest grunnleggende regulære uttrykkene er de som samsvarer med enkelttegn. Her er deres regler:

1. Et punktum (.) samsvarer med et hvilket som helst tegn. Hvis du trenger å søke etter et spesifikt punkt, må du unnslippe det ved å bruke "\"-tegnet (\.).

2. Et spørsmålstegn (?) indikerer at forrige tegn er valgfritt. For å søke etter selve spørsmålstegnet i en streng, må det også escapes med "\" (\?).

var text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit lest. Donec convallis dignissim ligula, et rutrum est elat vistibulum eu."; // Både "elit" og "elat" vil gjøre det. Prikken betyr at et hvilket som helst symbol vil gjøre det. var regex = /el.t/g; console.log(tekst.match(regex)); // "est" og "lest" vil fungere like bra. Spørsmålstegnet gjør "l" valgfritt. var regex2 = /l?est/g; console.log(tekst.match(regex2));

var tekst = "Lorem ipsum dolor sit amet, consectetur adipiscing elit lest. Donec convallis dignissim ligula, et rutrum est elat vistibulum eu.";

// Både "elit" og "elat" vil gjøre det. Prikken betyr at et hvilket som helst symbol vil gjøre det.

var regex = /el.t/g ;

konsoll. log(tekst. match(regex));

// "est" og "lest" vil fungere like bra. Spørsmålstegnet gjør "l" valgfritt.

var regex2 = /l?est/g ;

konsoll. log(tekst. match(regex2));

Match flere tegn

Et sett er ett eller flere tegn i parentes, for eksempel . Dette uttrykket vil bare se etter det settet med tegn i en streng – i dette eksemplet er det bare a, b eller c. Tvert imot kan du søke etter forekomster av alle symboler bortsett fra ved å bruke «^»-symbolet. [^abc] vil samsvare med alle tegn som ikke er a, b eller c. Du kan også angi en rekke tegn eller tall, for eksempel .

Det er innebygde tegnsett som gjør det lettere å skrive regulære uttrykk. De kalles forkortelser eller stenografi. For eksempel kan du skrive \D i stedet. Det finnes forkortelser for andre tegn (inkludert tall og understrek) - \w og \W, samt for mellomrom - \s og \S.

// Bare "katt" og "kan" vil fungere, ikke "bil". var text = "kattebil kan"; console.log(text.match(/ca/g)); // Alt vil passere bortsett fra katt og kan (det er et ^-symbol) console.log(text.match(/ca[^tn]/g)); // Et annet eksempel hvor bare tall vil sende tekst = "Jeg vil gjerne ha 8 kopper kaffe, takk."; console.log("Hvor mange kopper: " + text.match(//g)); // Enklere måte å bruke snarveien \d console.log("Hvor mange kopper: " + text.match(/\d/g)); // Sender alt unntatt tall console.log(text.match(/\D/g));

// Bare "katt" og "kan" vil fungere, ikke "bil".

var text = "kattebil kan" ;

konsoll. log(tekst. match(/ca/g));

// Passerer alt unntatt katt og kan (det er et ^-symbol)

konsoll. log (tekst . match (/ca[^tn]/g) );

// Et annet eksempel hvor bare tall vil passere

tekst = "Jeg vil gjerne ha 8 kopper kaffe, takk.";

konsoll. log ("Hvor mange kopper: " + tekst . match (//g) );

// Enklere måte å bruke snarvei \d

konsoll. log("Hvor mange kopper: " + tekst . match (/\d/g) );

// Passerer alt unntatt tall

konsoll. log(tekst. match(/\D/g));

Matchende ord

I de fleste tilfeller må du søke etter hele ord, ikke individuelle tegn. Dette gjøres ved å bruke modifikatorer (+) og (-), som gjentar et tegn eller sett med tegn.

Å legge til (X) spesifiserer det nøyaktige antallet repetisjoner, (x, y) – området (x og y er tall).

I tillegg er det et spesielt mønster \b som samsvarer med grenser på slutten av ord.

var text = "Hei folk fra 1974. Jeg kommer fra fremtiden. I 2014 har vi laserpistoler, svevebrett og bor på månen!"; // Vil finne år. \d+ vil matche ett eller flere tegn var yearRegex = /\d+/g; console.log("År: ", text.match(yearRegex)); // Finner alle setninger. Setningene våre begynner med stor bokstav og slutter med punktum eller utropstegn. var setningRegex = /.+?(\.|!)/g; console.log("Setninger: ", text.match(setningRegex)); // Finner alle ord som begynner med "h". Både store og små bokstaver passer for oss, så vi bruker i // \b-modifikatoren for å definere ordet grense. var hWords = /\bh\w+/ig; console.log("H Words: ", text.match(hWords)); // Finner alle ord fra 4 til 6 tegn var findWords = /\b\w(4,6)\b/g; console.log("Ord mellom 4 og 6 tegn: ", text.match(findWords)); // Finn ord som er lengre enn 5 tegn console.log("Ord 5 tegn eller lengre: ", text.match(/\b\w(5,)\b/g)); // Finner ord nøyaktig 6 tegn lange console.log("Ord nøyaktig 6 tegn lange: ", text.match(/\b\w(6)\b/g));

var tekst = "Hei folk fra 1974. Jeg kommer fra fremtiden. I 2014 har vi laserpistoler, svevebrett og bor på månen!";

// Vil finne år. \d+ samsvarer med ett eller flere tegn

var yearRegex = /\d+/g ;

konsoll. log ("År: ", tekst . match (yearRegex) );

// Finner alle setninger. Setningene våre begynner med stor bokstav og slutter med punktum eller utropstegn.

var setningRegex = /.+?(\.|!)/g ;

konsoll. log("Setninger: ", tekst. match(setningRegex));

// Finner alle ord som begynner med "h". Både store og små bokstaver passer for oss, så vi bruker i-modifikatoren

// \b for å bestemme ordgrenser.

var hWords = /\bh\w+/i g ;

konsoll. log ("H Words: ", tekst . match (hWords) );

// Finner alle ord fra 4 til 6 tegn

var findWords = /\b\w(4,6)\b/g ;

konsoll. Logg( "Ord mellom 4 og 6 tegn: ", tekst. match(findWords));

// Finn ord som er lengre enn 5 tegn

konsoll. log ("Ord 5 tegn eller lengre: " , tekst . samsvarer med (/\b\w(5,)\b/g ) );

// Finn ord på nøyaktig 6 tegn

konsoll. Logg( "Ord nøyaktig 6 tegn lange: ", tekst. match (/\b\w(6)\b/g) );

Hel strengvalidering

I JavaScript kan slike uttrykk brukes til å validere brukerinndata fra tekstfelt. For å validere strenger, brukes et regulært regulært uttrykk, knyttet til begynnelsen og slutten av et tekstfragment, ved å bruke uttrykkene ^ (begynnelsen av linjen) og $ (slutten av linjen) for dette formålet. Disse symbolene sikrer at mønsteret du skriver spenner over hele tekstens lengde og ikke bare samsvarer med en del av den.

I tillegg bruker vi i dette tilfellet test()-metoden til regex-objektet, som returnerer true eller false når vi tester om det regulære uttrykket samsvarer med strengen.

// Vi har en rekke strenger, la oss finne lenker..com/", "123461", "https://site/?s=google", "http://ikke en gyldig url", "abc http: / /invalid.url/" ]; var regex = /^https?:\/\/[\w\/?.&-=]+$/; var urls = ; for(var i = 0; i< strings.length; i++){ if(regex.test(strings[i])){ // Валидная ссылка urls.push(strings[i]); } } console.log("Valid URLs: ", urls);

// Vi har en rekke strenger, la oss finne lenkene.

var strenger = [

"https://site/" ,

"dette er ikke en URL" ,

"https://google.com/" ,

"123461" ,

"https://site/?s=google" ,

"http://ikke en gyldig url" ,

"abc http://ugyldig.url/"

var regex = / ^ https ? : \ / \ / [ \ w \ / ? . & -= ] + $ / ;

var urls = ;

for (var i = 0 ; i< strings . length ; i ++ ) {

if (regex . test (strenger [i ] ) ) (

nettadresser. push(strenger[i]);

konsoll. log("Gyldige nettadresser: ", nettadresser);

Søk og erstatt

En annen felles oppgave, som er tilrettelagt ved bruk av regulære uttrykk, søker og erstatter tekst.

Vanlig uttrykk

Vanlig uttrykk er et objekt som beskriver et tegnmønster. RegExp-klassen i JavaScript representerer regulære uttrykk, og String- og RegExp-klasseobjektene definerer metoder som bruker regulære uttrykk for å utføre mønstertilpasning og tekstsøk og erstatningsoperasjoner. Regelmessige uttrykks grammatikk i JavaScript inneholder en ganske komplett delmengde av regulære uttrykkssyntaks som brukes i Perl 5, så hvis du har erfaring med Perl-språket kan du enkelt beskrive mønstre i JavaScript-programmer.

Funksjoner i Perl regulære uttrykk som ikke støttes i ECMAScript inkluderer flaggene s (enkeltlinjemodus) og x (utvidet syntaks); escape-sekvenser \a, \e, \l, \u, \L, \U, \E, \Q, \A, \Z, \z og \G og andre utvidede konstruksjoner som starter med (?.

Definere regulære uttrykk

I JavaScript vanlig uttrykk er representert av objekter RegExp. RegExp-objekter kan opprettes ved å bruke RegExp()-konstruktøren, men oftere lages de ved hjelp av en spesiell bokstavlig syntaks. Akkurat som strengliteraler er spesifisert som tegn omgitt av anførselstegn, spesifiseres literaler i regulære uttrykk som tegn omgitt av et par skråstrektegn (/). Så JavaScript-koden din kan inneholde linjer som dette:

Var mønster = /s$/;

Denne linjen oppretter et nytt RegExp-objekt og tilordner det til mønstervariabelen. Dette objektet RegExp ser etter strenger som slutter med en "s". Det samme regulære uttrykket kan defineres ved å bruke RegExp()-konstruktøren:

Var mønster = new RegExp("s$");

En mønsterspesifikasjon for regulære uttrykk består av en sekvens av tegn. De fleste tegnene, inkludert alle alfanumeriske, beskriver bokstavelig talt tegnene som må være til stede. Det vil si at det regulære uttrykket /java/ samsvarer med alle linjer som inneholder delstrengen "java".

Andre tegn i regulære uttrykk er ikke ment å brukes for å finne deres eksakte ekvivalenter, men har heller spesielle betydninger. For eksempel inneholder det regulære uttrykket /s$/ to tegn. Det første tegnet s angir et søk etter et bokstavelig tegn. For det andre er $ et spesielt metategn som markerer slutten på en linje. Så dette regulære uttrykket samsvarer med enhver streng som slutter med tegnet s.

De følgende delene beskriver de ulike tegnene og metategnene som brukes i regulære uttrykk i JavaScript.

Bokstavelige tegn

Som nevnt tidligere samsvarer alle alfabetiske tegn og tall i regulære uttrykk seg selv. Syntaks for regulære uttrykk i JavaScript støtter også muligheten til å spesifisere visse ikke-alfabetiske tegn ved å bruke escape-sekvenser som starter med et omvendt skråstrek (\). For eksempel samsvarer sekvensen \n med nylinjetegnet. Disse symbolene er oppført i tabellen nedenfor:

Noen skilletegn har spesielle betydninger i vanlige uttrykk:

^ $ . * + ? = ! : | \ / () { } -

Betydningen av disse symbolene er forklart i de følgende avsnittene. Noen av dem har spesiell betydning bare i visse regulære uttrykkskontekster, mens de i andre sammenhenger tolkes bokstavelig. Men generelt, for å bokstavelig talt inkludere noen av disse tegnene i et regulært uttrykk, må du gå foran det med et omvendt skråstrek. Andre tegn, som anførselstegn og @, har ingen spesiell betydning og matcher ganske enkelt seg selv i vanlige uttrykk.

Hvis du ikke husker nøyaktig hvilke tegn som skal innledes med en \, kan du trygt sette en omvendt skråstrek foran hvilke som helst av tegnene. Men husk at mange bokstaver og tall blir spesiell betydning, så bokstavene og tallene du leter etter skal bokstavelig talt ikke ha et \-tegn foran. For å inkludere selve skråstrek-tegnet i et regulært uttrykk, må du åpenbart gå foran det med et annet skråstrek-tegn. Følgende regulære uttrykk samsvarer for eksempel med enhver streng som inneholder et omvendt skråstrek: /\\/.

Karakterklasser

Individuelle bokstavelige tegn kan kombineres til karakterklasser ved å sette dem i hakeparenteser. En tegnklasse samsvarer med ethvert tegn i den klassen. Derfor samsvarer det regulære uttrykket // med et av tegnene a, b eller c.

Negative tegnklasser kan også defineres for å matche alle tegn bortsett fra de som er spesifisert i parentes. Negasjonstegnklassen er spesifisert av tegnet ^ som det første tegnet etter venstre parentes. Det regulære uttrykket /[^abc]/ samsvarer med andre tegn enn a, b eller c. I tegnklasser kan en rekke tegn spesifiseres ved hjelp av en bindestrek. Alle små latinske tegn finnes ved å bruke //-uttrykket, og enhver bokstav eller tall fra det latinske tegnsettet kan bli funnet ved å bruke //-uttrykket.

Visse tegnklasser er spesielt vanlige, så syntaks for regulære uttrykk i JavaScript inkluderer spesialtegn og escape-sekvenser for å representere dem. Dermed samsvarer \s mellomrom, tabulator og eventuelle Unicode-mellomromstegn, og \S samsvarer med alle ikke-Unicode-mellomromstegn.

Tabellen nedenfor gir en liste over disse spesialtegnene og syntaksen til tegnklassene. (Merk at noen av tegnklassens escape-sekvenser bare samsvarer med ASCII-tegn og er ikke utvidet til å fungere med Unicode-tegn. Du kan eksplisitt definere dine egne Unicode-tegnklasser, for eksempel /[\u0400-\u04FF]/ matcher et hvilket som helst kyrillisk alfabet .)

JavaScript-karakterklasser med regulære uttrykk
Symbol Korrespondanse
[...] Alle tegnene som vises i parentes
[^...] Noen av tegnene som ikke er oppført i parentes
. Ethvert tegn annet enn en ny linje eller annen Unicode-linjeskilletegn
\w Ethvert ASCII-teksttegn. Tilsvarende
\W Ethvert tegn som ikke er et ASCII-teksttegn. Tilsvarer [^a-zA-Z0-9_]
\s Ethvert mellomromstegn fra Unicode-settet
\S Ethvert tegn uten mellomrom fra Unicode-settet. Vær oppmerksom på at tegnene \w og \S ikke er det samme
\d Eventuelle ASCII-nummer. Tilsvarende
\D Alle andre tegn enn ASCII-tall. Tilsvarer [^0-9]
[\b] Tilbaketegn bokstavelig

Merk at escape-sekvenser for klassespesialtegn kan omsluttes av hakeparenteser. \s samsvarer med et mellomromstegn og \d samsvarer med et hvilket som helst siffer, derav /[\s\d]/ samsvarer med ethvert mellomromstegn eller siffer.

Gjentakelse

Gitt kunnskapen om regulære uttrykkssyntaks oppnådd så langt, kan vi beskrive et tosifret tall som /\d\d/ eller et firesifret tall som /\d\d\d\d/, men vi kan ikke f.eks. , beskriv et tall som består av et hvilket som helst antall sifre, eller en streng med tre bokstaver etterfulgt av et valgfritt siffer. Disse mer komplekse mønstrene bruker regulære uttrykkssyntaks, som spesifiserer hvor mange ganger et gitt regulært uttrykkselement kan gjentas.

Gjenta symboler følger alltid mønsteret de er brukt på. Noen typer repetisjoner brukes ganske ofte, og spesielle symboler er tilgjengelige for å indikere disse tilfellene. For eksempel matcher + én eller flere forekomster av det forrige mønsteret. Følgende tabell gir et sammendrag av repetisjonssyntaksen:

Følgende linjer viser flere eksempler:

Var-mønster = /\d(2,4)/; // Matcher et tall som inneholder to til fire sifre mønster = /\w(3)\d?/; // Match nøyaktig tre ordtegn og ett valgfritt siffermønster = /\s+java\s+/; // Matcher ordet "java" med ett eller flere mellomrom // før og etter mønster = /[^(]*/; // Matcher null eller flere tegn bortsett fra åpningsparentesen

Vær forsiktig når du bruker repetisjonstegn * og ?. De kan matche fraværet av et mønster spesifisert foran dem og derfor fraværet av tegn. For eksempel samsvarer det regulære uttrykket /a*/ med strengen "bbbb" fordi det ikke inneholder tegnet a.

Repetisjonstegnene som er oppført i tabellen, representerer det maksimalt mulige antallet repetisjoner som gjør det mulig å matche påfølgende deler av det regulære uttrykket. Vi sier at dette er grådig gjentakelse. Det er også mulig å implementere repetisjon utført på en ikke-grådig måte. Det er nok å indikere etter symbolet (eller symbolene) repetisjonen spørsmålstegn: ??, +?, *? eller til og med (1,5)?.

For eksempel samsvarer det regulære uttrykket /a+/ med en eller flere forekomster av bokstaven a. Brukt på strengen "aaa", samsvarer den med alle tre bokstavene. På den annen side samsvarer uttrykket /a+?/ en eller flere forekomster av bokstaven a og velger minst mulig antall tegn. Påført den samme strengen, samsvarer dette mønsteret bare med den første bokstaven a.

"Grådløs" repetisjon gir ikke alltid det forventede resultatet. Tenk på mønsteret /a+b/, som samsvarer med en eller flere a-er etterfulgt av en b-er. Når den brukes på strengen "aaab", tilsvarer den hele strengen.

La oss nå sjekke den "ikke-grådige" versjonen av /a+?b/. Man skulle kanskje tro at det ville samsvare med en b med bare én a foran. Hvis brukt på samme streng, vil "aaab" forventes å matche enkelttegnet a og siste tegn b. Imidlertid matcher dette mønsteret faktisk hele strengen, akkurat som den grådige versjonen. Faktum er at et regulært uttrykksmønstersøk utføres ved å finne den første posisjonen i strengen, fra hvilken en match blir mulig. Siden et samsvar er mulig fra det første tegnet i strengen, vurderes ikke kortere samsvar fra påfølgende tegn engang.

Alternativer, gruppering og lenker

Grammatikk for regulære uttrykk inkluderer spesialtegn for å definere alternativer, gruppere underuttrykk og referanser til tidligere underuttrykk. Rørsymbol | tjener til å skille alternativer. For eksempel, /ab|cd|ef/ samsvarer med enten strengen "ab", eller strengen "cd", eller strengen "ef", og mønsteret /\d(3)|(4)/ samsvarer med enten tre sifre eller fire små bokstaver.

Legg merke til at alternativer behandles fra venstre til høyre til en treff blir funnet. Hvis en match blir funnet med venstre alternativ, ignoreres den høyre, selv om en "bedre" match kan oppnås. Derfor, når mønsteret /a|ab/ brukes på strengen "ab", vil det bare samsvare med det første tegnet.

Parenteser har flere betydninger i regulære uttrykk. En av dem er å gruppere individuelle elementer i ett underuttrykk, slik at elementene ved bruk av spesialtegnene |, *, +, ? og andre betraktes som en helhet. For eksempel, mønsteret /java(script)?/ samsvarer med ordet "java" etterfulgt av det valgfrie ordet "script", og /(ab|cd)+|ef)/ samsvarer med enten strengen "ef" eller en eller flere repetisjoner av en fra strengene "ab" eller "cd".

En annen bruk av parenteser i regulære uttrykk er å definere undermønstre innenfor et mønster. Når det finnes et samsvar med regulære uttrykk i målstrengen, kan den delen av målstrengen som samsvarer med et spesifikt undermønster i parentes trekkes ut.

Anta at du vil finne en eller flere små bokstaver etterfulgt av ett eller flere tall. For å gjøre dette kan du bruke malen /+\d+/. Men la oss også anta at vi kun vil ha tallene på slutten av hver kamp. Hvis vi setter denne delen av mønsteret i parentes (/+(\d+)/), kan vi trekke ut tall fra alle treff vi finner. Hvordan dette gjøres vil bli beskrevet nedenfor.

En relatert bruk av parentetiske underuttrykk er å referere til underuttrykk fra en tidligere del av det samme regulære uttrykket. Dette oppnås ved å spesifisere ett eller flere sifre etter \-tegnet. Tallene refererer til plasseringen av underuttrykket i parentes innenfor det regulære uttrykket. For eksempel refererer \1 til det første underuttrykket, og \3 refererer til det tredje. Merk at underuttrykk kan nestes i hverandre, så posisjonen til venstre parentes brukes ved telling. For eksempel, i følgende regulære uttrykk, vil en nestet underuttrykk (skript)-referanse se ut som \2:

/(ava(skript)?)\sis\s(moro\w*)/

En referanse til et tidligere underuttrykk peker ikke til mønsteret til det underuttrykket, men til teksten funnet som samsvarer med det mønsteret. Derfor kan referanser brukes til å pålegge en begrensning som velger deler av en streng som inneholder nøyaktig de samme tegnene. Følgende regulære uttrykk samsvarer for eksempel med null eller flere tegn innenfor enkle eller doble anførselstegn. Det krever imidlertid ikke at åpnings- og avsluttende sitater samsvarer med hverandre (det vil si at begge sitatene er enkle eller doble):

/[""][^""]*[""]/

Vi kan kreve at anførselstegn samsvarer med en referanse som dette:

Her matcher \1 det første underuttrykket. I dette eksemplet pålegger koblingen en begrensning som krever at det avsluttende anførselstegnet samsvarer med det innledende anførselstegnet. Dette regulære uttrykket tillater ikke enkle anførselstegn innenfor doble anførselstegn, og omvendt.

Det er også mulig å gruppere elementer i et regulært uttrykk uten å opprette en nummerert referanse til disse elementene. I stedet for bare å gruppere elementer mellom ( og ), start gruppen med symboler (?: og avslutt den med et symbol). Tenk for eksempel på følgende mønster:

/(ava(?:cript)?)\sis\s(moro\w*)/

Her er underuttrykket (?:cript) kun nødvendig for gruppering slik at repetisjonstegnet ? kan brukes på gruppen. Disse modifiserte parentesene lager ikke en kobling, så i dette regulære uttrykket refererer \2 til tekst som samsvarer med mønsteret (moro\w*).

Følgende tabell viser utvalgs-, grupperings- og referanseoperatorene i regulære uttrykk:

Regelmessige uttrykkssymboler for å velge fra alternativer, gruppering og JavaScript-lenker
Symbol Betydning
| Alternativ. Matcher enten underuttrykket til venstre eller underuttrykket til høyre.
(...) Gruppering. Grupperer elementer i en enkelt enhet som kan brukes med tegnene *, +, ?, | og så videre. Husker også tegn som samsvarer med denne gruppen for bruk i etterfølgende referanser.
(?:...) Bare gruppering. Grupperer elementer i en enkelt enhet, men husker ikke tegnene som tilsvarer denne gruppen.
\Antall Matcher de samme tegnene som ble funnet når gruppenummeret ble matchet. Grupper er underuttrykk innenfor (muligens nestede) parenteser. Gruppenummer tildeles ved å telle venstre parentes fra venstre til høyre. Grupper dannet ved hjelp av symbolene (?:) er ikke nummerert.

Spesifisere en kampposisjon

Som beskrevet tidligere samsvarer mange elementer i et regulært uttrykk med et enkelt tegn i en streng. For eksempel samsvarer \s med et enkelt mellomromstegn. Andre regulære uttrykkselementer samsvarer med plasseringene mellom tegnene i stedet for selve tegnene. For eksempel samsvarer \b med en ordgrense – grensen mellom \w (et ASCII-teksttegn) og \W (et ikke-teksttegn), eller grensen mellom et ASCII-teksttegn og begynnelsen eller slutten av en linje.

Elementer som \b spesifiserer ingen tegn som må være til stede i den samsvarende strengen, men de spesifiserer gyldige posisjoner for samsvar. Disse elementene kalles noen ganger regulære uttrykksankerelementer fordi de forankrer mønsteret til en bestemt posisjon i strengen. De mest brukte ankerelementene er ^ og $, som knytter mønstre til henholdsvis begynnelsen og slutten av en linje.

For eksempel kan ordet "JavaScript" på sin egen linje bli funnet ved å bruke det regulære uttrykket /^JavaScript$/. Å finne eget ord"Java" (i stedet for et prefiks, for eksempel i ordet "JavaScript"), kan du prøve å bruke mønsteret /\sJava\s/, som krever et mellomrom før og etter ordet.

Men en slik løsning reiser to problemer. For det første vil den bare finne ordet "Java" hvis det er omgitt av mellomrom på begge sider, og vil ikke kunne finne det på begynnelsen eller slutten av linjen. For det andre, når dette mønsteret stemmer, vil strengen den returnerer inneholde ledende og etterfølgende mellomrom, noe som ikke er akkurat det vi ønsker. Så i stedet for å bruke et mønster som samsvarer med mellomromstegn \s, bruker vi et mønster (eller anker) som samsvarer med ordgrenser \b. Resultatet blir følgende uttrykk: /\bJava\b/.

Ankerelementet \B samsvarer med en posisjon som ikke er en ordgrense. Det vil si at mønsteret /\Bcript/ vil samsvare med ordene "JavaScript" og "postscript" og vil ikke samsvare med ordene "script" eller "Scripting".

Vilkårlige regulære uttrykk kan også tjene som ankerbetingelser. Hvis du plasserer et uttrykk mellom tegnene (?= og), blir det en forovermatchtest mot påfølgende tegn, som krever at disse tegnene samsvarer med det angitte mønsteret, men ikke inkluderes i samsvarsstrengen.

For eksempel, for å matche navnet på et vanlig programmeringsspråk etterfulgt av et kolon, kan du bruke uttrykket /ava(cript)?(?=\:)/. Dette mønsteret samsvarer med ordet "JavaScript" i strengen "JavaScript: The Definitive Guide", men det vil ikke samsvare med ordet "Java" i strengen "Java i et nøtteskall" fordi det ikke etterfølges av et kolon.

Hvis du skriver inn betingelsen (?!), vil dette være en negativ foroversjekk for påfølgende tegn, som krever at følgende tegn ikke samsvarer med det angitte mønsteret. For eksempel mønsteret /Java(?!Script)(\w* )/ samsvarer med delstrengen "Java", etterfulgt av en stor bokstav og et hvilket som helst tall tekst ASCII-tegn forutsatt at understrengen "Java" ikke følges av understrengen "Script". Den vil matche strengen "JavaBeans", men ikke strengen "Javanese", og den vil matche strengen "JavaScrip", men ikke strengene "JavaScript" eller "JavaScripter".

Tabellen nedenfor gir en liste over ankertegn for regulære uttrykk:

Ankerkarakterer for regulære uttrykk
Symbol Betydning
^ Tilsvarer begynnelsen av et strenguttrykk eller begynnelsen av en linje i et flerlinjesøk.
$ Tilsvarer slutten av et strenguttrykk eller slutten av en linje i et flerlinjesøk.
\b Matcher en ordgrense, dvs. samsvarer med posisjonen mellom et \w-tegn og et \W-tegn, eller mellom et \w-tegn og begynnelsen eller slutten av en linje. (Merk imidlertid at [\b] samsvarer med backspace-tegnet.)
\B Matcher en posisjon som ikke er en ordgrense.
(?=p) Positiv sjekk fremover for påfølgende karakterer. Krever påfølgende tegn for å matche mønsteret p, men inkluderer ikke disse tegnene i den samsvarende strengen.
(?!p) Negativ foroversjekk for påfølgende tegn. Krever at følgende tegn ikke samsvarer med mønsteret s.

Flagg

Og en til, siste element regulære uttrykks grammatikker. Regulære uttrykksflagg spesifiserer mønstersamsvarsregler på høyt nivå. I motsetning til resten av grammatikken i regulære uttrykk, er flagg ikke spesifisert mellom skråstrekene, men etter det andre. JavaScript støtter tre flagg.

Flagg i spesifiserer at mønstertilpasning ikke skal skille mellom store og små bokstaver, og flagg g- at søket skal være globalt, dvs. alle treff i strengen må finnes. Flagg m utfører et mønstersøk i flerlinjemodus. Hvis strenguttrykket det søkes om inneholder nylinjer, vil ankertegnene ^ og $ i denne modusen, i tillegg til å matche begynnelsen og slutten av hele strenguttrykket, også samsvare med begynnelsen og slutten av hvert tekststreng. For eksempel matcher mønsteret /java$/im både "java" og "Java\nis fun".

Disse flaggene kan kombineres i hvilken som helst kombinasjon. For å søke etter den første forekomsten av ordet "java" (eller "Java", "JAVA" osv.) på en måte som ikke skiller mellom store og små bokstaver, kan du bruke det regulære uttrykket /\bjava\b/ som ikke skiller mellom store og små bokstaver. Jeg. Og for å finne alle forekomster av dette ordet i en streng, kan du legge til g-flagget: /\bjava\b/gi.

Metoder i String-klassen for søk etter mønster

Frem til dette punktet har vi diskutert grammatikken til de regulære uttrykkene vi lager, men vi har ikke sett på hvordan disse regulære uttrykkene faktisk kan brukes i JavaScript-skript. I denne delen vil vi diskutere metoder Strengeobjekt, der regulære uttrykk brukes for mønstermatching og søk med erstatning. Og så vil vi fortsette samtalen om mønstertilpasning med regulære uttrykk ved å se på RegExp-objektet og dets metoder og egenskaper.

Strings støtter fire metoder som bruker regulære uttrykk. Den enkleste av dem er metoden Søk(). Det tar et regulært uttrykk som et argument og returnerer enten posisjonen til det første tegnet i den samsvarende delstrengen, eller -1 hvis ingen samsvar blir funnet. For eksempel vil følgende anrop returnere 4:

Var result = "JavaScript".search(/script/i); // 4

Hvis argumentet til search()-metoden ikke er et regulært uttrykk, konverteres det først ved å sende det til RegExp-konstruktøren. Search()-metoden støtter ikke globalt søk og ignorerer g-flagget i argumentet.

Metode erstatte() utfører en søk og erstatt operasjon. Det tar et regulært uttrykk som det første argumentet og en erstatningsstreng som det andre. Metoden søker etter linjen som den kalles for samsvar med det angitte mønsteret.

Hvis det regulære uttrykket inneholder g-flagget, erstatter replace()-metoden alle treff funnet med erstatningsstrengen. Ellers erstatter den bare det første treffet som ble funnet. Hvis erstatte()-metodens første argument er en streng i stedet for et regulært uttrykk, utfører metoden et bokstavelig søk etter strengen i stedet for å konvertere den til et regulært uttrykk ved å bruke RegExp()-konstruktøren slik search()-metoden gjør.

Som et eksempel kan vi bruke erstatte()-metoden for å bruke store bokstaver i ordet "JavaScript" konsekvent over en hel tekstlinje:

// Uavhengig av store og små bokstaver, erstatter vi dem med et ord i det nødvendige tilfellet var result = "javascript".replace(/JavaScript/ig, "JavaScript");

Replace()-metoden er kraftigere enn dette eksemplet antyder. La meg minne deg på at underuttrykkene i parentes innenfor et regulært uttrykk er nummerert fra venstre mot høyre, og at det regulære uttrykket husker teksten som tilsvarer hvert av underuttrykkene. Hvis erstatningsstrengen inneholder et $-tegn etterfulgt av et tall, erstatter erstatte()-metoden de to tegnene med teksten som samsvarer med det angitte underuttrykket. Dette er en veldig nyttig funksjon. Vi kan for eksempel bruke det til å erstatte rette anførselstegn i en streng med typografiske anførselstegn, som simuleres av ASCII-tegn:

// Et sitat er et sitat etterfulgt av et hvilket som helst antall tegn // annet enn anførselstegn (som vi husker), etterfulgt av et annet anførselstegn // var quote = /"([^"]*)"/g; // Erstatt rette anførselstegn med typografiske og la "$1" være uendret // innholdet i sitatet lagret i $1 var text = ""JavaScript" er et tolket programmeringsspråk."; var result = text.replace(quote, ""$1"" ) ; // "JavaScript" er et tolket programmeringsspråk.

En viktig ting å merke seg er at det andre argumentet for replace() kan være en funksjon som dynamisk beregner erstatningsstrengen.

Metode kamp() er den mest generelle av String-klassemetodene som bruker regulære uttrykk. Det tar et regulært uttrykk som eneste argument (eller konverterer argumentet til et regulært uttrykk ved å sende det til RegExp()-konstruktøren) og returnerer en matrise som inneholder søkeresultatene. Hvis g-flagget er satt i det regulære uttrykket, returnerer metoden en matrise med alle samsvar som finnes i strengen. For eksempel:

// returnerer ["1", "2", "3"] var result = "1 pluss 2 er lik 3".match(/\d+/g);

Hvis det regulære uttrykket ikke inneholder g-flagget, utfører ikke match()-metoden et globalt søk; det ser bare etter den første kampen. Match() returnerer imidlertid en matrise selv når metoden ikke utfører et globalt søk. I dette tilfellet er det første elementet i matrisen understrengen som er funnet, og alle gjenværende elementer er underuttrykk av det regulære uttrykket. Derfor, hvis match() returnerer en array arr, vil arr inneholde hele strengen som ble funnet, arr understrengen som tilsvarer det første underuttrykket, osv. Ved å trekke en parallell med replace()-metoden kan vi si at innholdet i $n legges inn i arr[n].

Ta for eksempel en titt på følgende kode som analyserer en URL:

Var url = /(\w+):\/\/([\w.]+)\/(\S*)/; var text = "Besøk nettstedet vårt http://www..php"; var resultat = text.match(url); if (result != null) ( var fullurl = resultat; // Inneholder "http://www..php" var protocol = resultat; // Inneholder "http" var host = resultat; // Inneholder "www..php ")

Det skal bemerkes at for et regulært uttrykk som ikke har det globale søkeflagget g satt, returnerer match()-metoden samme verdi som det regulære uttrykkets exec()-metode: den returnerte matrisen har indeks- og input-egenskapene, som beskrevet i diskusjonen av exec( ) nedenfor.

Den siste av String-objektmetodene som bruker regulære uttrykk er dele(). Denne metoden deler strengen den kalles på i en rekke understrenger, ved å bruke argumentet som skilletegn. For eksempel:

"123.456.789". split(","); // Returner ["123","456","789"]

Split()-metoden kan også ta et regulært uttrykk som et argument. Dette gjør metoden kraftigere. Du kan for eksempel spesifisere et skilletegn som tillater et vilkårlig antall mellomrom på begge sider:

"1, 2, 3 , 4 , 5". split(/\s*,\s*/); // Returner ["1","2","3","4","5"]

RegExp-objekt

Som nevnt er regulære uttrykk representert som RegExp-objekter. I tillegg til RegExp()-konstruktøren støtter RegExp-objekter tre metoder og flere egenskaper.

RegExp()-konstruktøren tar ett eller to strengargumenter og lager et nytt RegExp-objekt. Det første argumentet til konstruktøren er en streng som inneholder kroppen til det regulære uttrykket, dvs. tekst som må vises mellom skråstrek i et regulært uttrykk. Merk at strengliteraler og regulære uttrykk bruker \-tegnet for å representere escape-sekvenser, så når du sender det regulære uttrykket som en streng-literal til RegExp()-konstruktøren, må du erstatte hvert \-tegn med et par \\-tegn.

Det andre argumentet til RegExp() kan mangle. Hvis det er spesifisert, definerer det regulære uttrykksflagg. Det må være et av tegnene g, i, m eller en kombinasjon av disse tegnene. For eksempel:

// Finner alle femsifrede tall i en streng. Merk // bruken av symboler i dette eksemplet \\ var zipcode = new RegExp("\\d(5)", "g");

RegExp()-konstruktøren er nyttig når det regulære uttrykket genereres dynamisk og derfor ikke kan representeres ved bruk av literal syntaks for regulære uttrykk. For å finne en streng som er skrevet inn av brukeren, må du for eksempel lage et regulært uttrykk ved kjøring ved å bruke RegExp().

RegExp-egenskaper

Hvert RegExp-objekt har fem egenskaper. Eiendom kilde- en skrivebeskyttet streng som inneholder teksten til det regulære uttrykket. Eiendom global er en skrivebeskyttet boolsk verdi som spesifiserer om g-flagget er til stede i det regulære uttrykket. Eiendom ignoreCase er en skrivebeskyttet boolsk verdi som bestemmer om i-flagget er til stede i det regulære uttrykket. Eiendom flerlinjet er en skrivebeskyttet boolsk verdi som bestemmer om m-flagget er til stede i det regulære uttrykket. Og den siste eiendommen lastIndex er et heltall som kan leses og skrives. For mønstre med g-flagget inneholder denne egenskapen posisjonsnummeret på linjen der neste søk skal begynne. Som beskrevet nedenfor, brukes den av metodene exec() og test().

RegExp-metoder

RegExp-objekter definerer to metoder som utfører mønstertilpasning; de oppfører seg på samme måte som String-klassemetodene beskrevet ovenfor. Hovedmetoden for RegExp-klassen som brukes for mønstertilpasning er exec(). Den ligner på den tidligere nevnte match()-metoden til String-klassen, bortsett fra at det er en RegExp-klassemetode som tar en streng som et argument, i stedet for en String-klassemetode som tar et RegExp-argument.

Exec()-metoden utfører det regulære uttrykket for den angitte strengen, dvs. ser etter en fyrstikk i en snor. Hvis ingen samsvar blir funnet, returnerer metoden null. Men hvis et samsvar blir funnet, returnerer det samme matrise som matrisen returnert av match()-metoden for søk uten g-flagget. Nullelementet i matrisen inneholder strengen som samsvarer med det regulære uttrykket, og alle påfølgende elementer inneholder understrenger som samsvarer med alle underuttrykk. I tillegg kommer eiendommen indeks inneholder posisjonsnummeret til tegnet som det tilsvarende fragmentet begynner med, og egenskapen input refererer til linjen som ble søkt.

I motsetning til match(), returnerer exec()-metoden en matrise hvis struktur ikke er avhengig av tilstedeværelsen av g-flagget i det regulære uttrykket. La meg minne deg på at når du sender et globalt regulært uttrykk, returnerer match()-metoden en rekke treff funnet. Og exec() returnerer alltid ett samsvar, men gir informasjon om det full informasjon. Når exec() kalles på et regulært uttrykk som inneholder g-flagget, setter metoden lastIndex-egenskapen til det regulære uttrykksobjektet til posisjonsnummeret til tegnet umiddelbart etter den funnet delstrengen.

Når exec() kalles en gang til på det samme regulære uttrykket, begynner det søket ved tegnet hvis posisjon er spesifisert i lastIndex-egenskapen. Hvis exec() ikke finner en treff, settes lastIndex-egenskapen til 0. (Du kan også sette lastIndex til null når som helst, noe som bør gjøres i alle tilfeller der søket avsluttes før siste treff i en enkelt rad er funnet, og søket begynner på en annen linje med det samme RegExp-objektet.) Denne spesielle virkemåten gjør at exec() kan kalles gjentatte ganger for å iterere over alle treff i det regulære uttrykket i linjen. For eksempel:

Var mønster = /Java/g; var text = "JavaScript er morsommere enn Java!"; var resultat; while((result = pattern.exec(text)) != null) ( console.log("Funnet "" + resultat + """ + " ved posisjon " + result.index + "; neste søk starter på " + mønster .lastIndex); )

En annen metode for RegExp-objektet er test(), som er mye enklere metode exec(). Den tar en streng og returnerer sann hvis strengen samsvarer med det regulære uttrykket:

Var mønster = /java/i; pattern.test("JavaScript"); // Returner sant

Å kalle test() tilsvarer å kalle exec(), som returnerer true hvis exec() returnerer noe annet enn null. Av denne grunn oppfører test()-metoden seg på samme måte som exec()-metoden når den kalles på et globalt regulært uttrykk: den begynner å søke etter den spesifiserte strengen på posisjonen spesifisert av lastIndex-egenskapen, og hvis den finner et samsvar , setter lastIndex-egenskapen til tegnposisjonsnummeret rett ved siden av det funnet samsvaret. Derfor, ved å bruke test()-metoden, kan du opprette en linjegjennomløpsløkke på samme måte som ved å bruke exec()-metoden.

I JavaScript er regulære uttrykk representert av RegExp-objekter. RegExp-objekter kan opprettes ved å bruke RegExp()-konstruktøren, men oftere lages de ved hjelp av en spesiell bokstavlig syntaks. Akkurat som strengliteraler er spesifisert som tegn omsluttet av anførselstegn, spesifiseres literaler for regulære uttrykk som tegn omsluttet av et skråstrekpar / .

/pattern/flags new RegExp("mønster"[, søkealternativer])

mønster- et regulært uttrykk for søk (mer om erstatning senere), og flagg - en streng med en hvilken som helst kombinasjon av tegn g (globalt søk), i (case-bok er ikke viktig) og m (multi-line search). Den første metoden brukes ofte, den andre - noen ganger. For eksempel er to slike samtaler likeverdige.

Søkealternativer

Når vi oppretter et regulært uttrykk, kan vi angi flere søkealternativer

Tegn i regulære JavaScript-uttrykk

SymbolKorrespondanse
Alfanumeriske tegnTilsvarer seg selv
\0 NUL-tegn (\u0000)
\tFane (\u0009)
\nLinjefeed (\u000A)
\vVertikal fane (\u000B)
\fSideoversettelse (\u000C)
\rvognretur (\u000D)
\xnnEt tegn fra det latinske settet, spesifisert av det heksadesimale tallet nn; for eksempel er \x0A det samme som \n
\uxxxxUnicode-tegn spesifisert med heksadesimalt nummer xxxx; for eksempel er \u0009 det samme som \t
\cXKontrolltegnet "X", for eksempel, sekvensen \cJ tilsvarer nylinjetegnet \n
\ For vanlige karakterer - gjør dem spesielle. For eksempel ser uttrykket /s/ ganske enkelt etter tegnet "s". Og hvis du setter \ foran s, angir /\s/ allerede et mellomromstegn. Og omvendt, hvis tegnet er spesielt, for eksempel *, vil \ gjøre det bare til et vanlig "stjernetegn". For eksempel søker /a*/ etter 0 eller flere påfølgende "a"-tegn. For å finne a med en stjerne "a*" - sett \ foran spesialen. symbol: /a\*/ .
^ Indikerer begynnelsen av inndataene. Hvis flerlinjes søkeflagget ("m") er satt, vil det også utløses ved starten av en ny linje. For eksempel vil ikke /^A/ finne "A" i "en A", men vil finne den første "A" i "En A."
$ Indikerer slutten på inndataene. Hvis flerlinjers søkeflagget er satt, vil det også fungere på slutten av linjen. For eksempel vil ikke /t$/ finne "t" i "eater", men det vil finne det i "eat".
* Indikerer repetisjon 0 eller flere ganger. For eksempel vil /bo*/ finne "boooo" i "A spøkelse booooed" og "b" i "A bird warbled", men vil ikke finne noe i "En geit gryntet".
+ Indikerer repetisjon 1 eller flere ganger. Tilsvarer (1,). For eksempel vil /a+/ samsvare med "a" i "godteri" og alle "a" i "caaaaaaandy".
? Indikerer at elementet kan være til stede eller ikke. For eksempel vil /e?le?/ samsvare med "el" i "angel" og "le" i "angle." Hvis den brukes umiddelbart etter en av kvantifikatoren * , + , ? , eller () , spesifiserer deretter et "ikke-grådig" søk (som gjentar minimum antall ganger mulig, til nærmeste neste mønsterelement), i motsetning til standard "grådig"-modus, der antallet repetisjoner er maksimalt, selv om det neste mønsterelementet også stemmer overens. I tillegg, ? brukt i forhåndsvisningen, som er beskrevet i tabellen under (?=), (?!) og (?:) .
. (desimaltegnet) representerer ethvert tegn annet enn en ny linje: \n \r \u2028 eller \u2029. (du kan bruke [\s\S] for å søke etter et hvilket som helst tegn, inkludert nylinjer). For eksempel vil /.n/ matche "an" og "on" i "nei, et eple er på treet", men ikke "nei".
(x)Finner x og husker. Dette kalles "minneparenteser". For eksempel vil /(foo)/ finne og huske "foo" i "foo bar." Den funnet understrengen lagres i søkeresultatarrayen eller i de forhåndsdefinerte egenskapene til RegExp-objektet: $1, ..., $ 9. I tillegg kombinerer parentesene det som finnes i dem til et enkelt mønsterelement. For eksempel (abc)* - gjenta abc 0 eller flere ganger.
(?:x)Finner x, men husker ikke hva den finner. Dette kalles "minneparenteser". Den funnet delstrengen lagres ikke i egenskapene til resultatmatrisen og RegExp. Som alle parenteser kombinerer de det som er i dem til ett enkelt undermønster.
x(?=y)Finner x bare hvis x etterfølges av y. For eksempel vil /Jack(?=Sprat)/ bare matche "Jack" hvis den blir fulgt av "Sprat". /Jack(?=Sprat|Frost)/ vil bare matche "Jack" hvis den blir fulgt av "Sprat" eller "Frost". Imidlertid vil verken "Sprat" eller "Frost" vises i søkeresultatet.
x(?!y)Finner x bare hvis x ikke er etterfulgt av y. For eksempel vil /\d+(?!\.)/ bare samsvare med et tall hvis det ikke etterfølges av et desimaltegn. /\d+(?!\.)/.exec("3.141") vil finne 141, men ikke 3.141.
x|yFinner x eller y. For eksempel vil /grønn|rød/ samsvare med "grønt" i "grønt eple" og "rødt" i "rødt eple".
(n)Hvor n er et positivt heltall. Finner nøyaktig n repetisjoner av det foregående elementet. For eksempel vil ikke /a(2)/ finne "a" i "godteri", men vil finne både a-er i "caandy" og de to første a-ene i "caaandy".
(n,)Hvor n er et positivt heltall. Finner n eller flere repetisjoner av et element. For eksempel vil ikke /a(2,) finne "a" i "godteri", men vil finne alle "a" i "caandy" og i "caaaaaaandy."
(n,m)Hvor n og m er positive heltall. Finn fra n til m repetisjoner av elementet.
Karaktersett. Finner alle de oppførte tegnene. Du kan angi avstand ved å bruke en bindestrek. For eksempel - det samme som . Matcher "b" i "brisket" og "a" og "c" i "verk".
[^xyz]Alle andre tegn enn de som er spesifisert i settet. Du kan også angi et spenn. For eksempel er [^abc] det samme som [^a-c] . Finner "r" i "brisket" og "h" i "chop".
[\b]Finner tilbaketegn. (Ikke å forveksle med \b .)
\bFinner en (latinsk) ordgrense, for eksempel et mellomrom. (Ikke å forveksle med [\b]). For eksempel vil /\bn\w/ matche "nei" i "middag"; /\wy\b/ vil finne "ly" i "muligens i går."
\BDet angir ikke en ordgrense. For eksempel vil /\w\Bn/ samsvare med "på" i "middag på dagen", og /y\B\w/ vil samsvare med "ye" i "muligens i går."
\cXHvor X er en bokstav fra A til Å. Indikerer et kontrolltegn i en streng. For eksempel representerer /\cM/ tegnet Ctrl-M.
\dfinner et tall fra et hvilket som helst alfabet (vårt er Unicode). Bruk for å finne vanlige tall. For eksempel vil /\d/ eller // samsvare med "2" i "B2 er serienummeret."
\DFinner et ikke-numerisk tegn (alle alfabeter). [^0-9] er ekvivalenten for vanlige tall. For eksempel vil /\D/ eller /[^0-9]/ samsvare med "B" i "B2 er serienummeret."
\sFinner alle mellomrom, inkludert mellomrom, tabulator, ny linje og andre Unicode-mellomrom. For eksempel vil /\s\w*/ matche "bar" i "foo bar."
\SFinner alle tegn unntatt mellomrom. For eksempel vil /\S\w*/ matche "foo" i "foo bar."
\vVertikalt tabulatortegn.
\wFinner et hvilket som helst ord (latinsk alfabet), inkludert bokstaver, tall og understreker. Tilsvarende. For eksempel vil /\w/ matche "a" i "eple", "5" i "$5,28" og "3" i "3D."
\WFinner alle ikke-(latinske) verbale tegn. Tilsvarer [^A-Za-z0-9_] . For eksempel vil /\W/ og /[^$A-Za-z0-9_]/ samsvare med "%" i "50%."

Arbeid med regulære uttrykk i Javascript

Arbeid med regulære uttrykk i Javascript implementeres av metoder i String-klassen

exec(regexp) - finner alle treff (oppføringer i det vanlige mønsteret) i en streng. Returnerer en matrise (hvis det er samsvar) og oppdaterer regexp-egenskapen, eller null hvis ingenting blir funnet. Med g-modifikatoren - hver gang denne funksjonen kalles, vil den returnere neste treff etter den forrige som ble funnet - dette implementeres ved å opprettholde en offset-indeks for det siste søket.

match(regexp) - finn en del av en streng ved å bruke et mønster. Hvis g-modifikatoren er spesifisert, returnerer match() en matrise med alle samsvar eller null (i stedet for en tom matrise). Uten g-modifikatoren fungerer denne funksjonen som exec();

test(regexp) - funksjonen sjekker en streng for å matche et mønster. Returnerer sant hvis det er samsvar, og usant hvis det ikke er samsvar.

split(regexp) - Splitter strengen den kalles opp i en rekke understrenger, ved å bruke argumentet som skilletegn.

replace(regexp, mix) - metoden returnerer en modifisert streng i samsvar med malen (regulært uttrykk). Den første parameteren til regexp kan også være en streng i stedet for et regulært uttrykk. Uten g-modifikatoren erstatter metoden i linjen bare den første forekomsten; med modifikatoren g - oppstår en global erstatning, dvs. alle forekomster i en gitt linje endres. mix - erstatningsmal, kan godta verdiene til en streng, erstatningsmal, funksjon (funksjonsnavn).

Spesialtegn i erstatningsstrengen

Utskifting via funksjon

Hvis du spesifiserer en funksjon som den andre parameteren, utføres den for hvert samsvar. En funksjon kan dynamisk generere og returnere en erstatningsstreng. Den første parameteren til funksjonen er den funnet understrengen. Hvis det første argumentet som skal erstattes er et RegExp-objekt, inneholder de neste n parameterne nestede parenteser. De to siste parametrene er posisjonen i linjen der treffet fant sted og selve linjen.