javascript - Kan vi bruke regex for å løse flere regler samtidig?


Jeg trenger å forhindre noe brukerinput-interaksjon, og det første som kommer til tankene mine er regex umiddelbart.

Jeg skal først skrive så godt jeg kan hva jeg trenger å oppnå, og så vil jeg publisere koden jeg skrev for å oppnå mesteparten av disse, men som fortsatt ikke er perfekt...

  • Ta tråden
  • Ikke tillat at det begynner å skrive med en space
  • Ikke tillat flere mellomrom kontinuerlig
  • Ikke tillat flere dots på rad
  • Ikke tillat flere apostrofer
  • Tillat følgende tegn [a-z] '.
  • Ikke tillat at strengen overskrider 14 tegn

Nå, her er koden min:

this.name = this.name
  .replace(/^[\s]+/, '')     // prevent starting with space
  .replace(/\s\s+/, ' ')     // prevent multiplace spaces
  .replace(/\.\./, '.')      // prevent multiple dots
  .replace(/''/, '\'')       // prevent multiple apostrophies
  .replace(/[^ a-z'.]/i, '') // allowed
  .toUpperCase()             // transform
  .substring(0, 14)          // do not allow more than 14 characters

Spørsmål :

  • Kan vi, og hvordan i så fall, oppnå alle disse eller de fleste av disse regex-reglene i én enkelt erstatning?

  • Hvordan kan jeg fikse/forbedre mine regex-regler for å ikke tillate mer enn én enkelt .? Jeg har laget det slik at det ikke tillater sammenhengende forekomster, men en bruker kan bruke to prikker som M.G.K - selv om jeg bare vil tillate én enkelt .-forekomst i hele strengen?

  • Det samme som ovenfor, men for ' (apostrof)?

Svar #1

Det første kravet om å "presse" alt inn i én regex-erstatningsoperasjon er ganske enkelt å implementere, fordi alle utskiftingene du må gjøre er å bruke karakterene du matcher. Du kan bruke .replace(/^\s+|( \s)\s+|(\.)\.|(')'|[^a-z'.]+/ig, '$1$2$3'), se denne regex-demoen.

Detaljer

  • ^\s+ - starten av strengen (^) og deretter 1+ mellomrom
  • | - eller
  • (\s)\s+ - et enkelt mellomrom fanget i Gruppe 1 og deretter 1+ mellomromstegn
  • | - eller
  • (\.)\. - en . fanget i Gruppe 2, og deretter en .
  • | - eller
  • (')' - en ' fanget i Gruppe 3 og deretter en '
  • | - eller
  • [^a-z'.]+ - 1 eller flere tegn unntatt mellomrom, ASCII-bokstav, ' og ..

Modifikatoren /i gjør at a-z matcher på en ikke-sensitiv måte, g aktiverer flere matcher. $1 refererer til verdien i Gruppe 1, $2 refererer til verdien i Gruppe 2, og $3 refererer til verdien i Gruppe 3. Merk at hvis de ikke matcher, er disse verdiene i gruppene tomme strenger, derfor kan vi bruke alle tre sammen i et enkelt erstatningsmønster for strenger.

Det andre og tredje kravet krever to separate regex-erstattingsoperasjoner til. Poenget er å matche og fange alle tegn frem til den andre forekomsten av ' og . og bare matche den andre forekomsten av ' og ., og deretter erstatte med tilbakehenvisningen til den første gruppen: 1) .replace(/^([^']*'[^']*)'/, '$1') (demo) og 2) .replace(/^([^.]*\.[^.]*)\./, '$1') (demo).

Detaljer

  • ^ - start på strenganker
  • ([^']*'[^']*) - Gruppe 1:

    • [^']* - hvilken som helst 0+ tegn unntatt ' (en [^...] er en negetert tegnklasse som matcher alle tegn unntatt de som er definert inne i klassen)
    • ' - et enkelt anførselstegn
    • [^']* - hvilken som helst 0+ tegn bortsett fra '
  • ' - et enkelt anførselstegn.

Denne matchen erstattes med $1, innholdet i den første fangstgruppen.

Det tredje mønsteret er analogt med det andre mønsteret, bare ' er erstattet med ./\. (merk at inne i en tegnklasse behandles . som et bokstavelig ., det matcher ingen tegn bortsett fra linjeskifttegn inne i [...]).