Python

Reguliere expressies met Python 3

Reguliere expressies met Python 3
Reguliere expressies worden vaak gezien als deze echt obscure reeks hiërogliefen die men gewoonlijk van internet kopieert en in zijn/haar code plakt. Deze mysterieuze spreuk toont dan magische mogelijkheden om patronen te vinden in tekststrings en als we het vriendelijk vragen, zal het ons zelfs een plezier doen om een ​​bepaald patroon binnen een string te vervangen door iets mooiers.

Als u bijvoorbeeld handlers voor URL schrijft (en God helpe u als u er een helemaal opnieuw schrijft), dan wilt u vaak hetzelfde resultaat weergeven, ongeacht de trailing '/' in de URL. E.g https://voorbeeld.com/gebruiker/instellingen/ en https://voorbeeld.com/user/settings zouden beide naar dezelfde pagina moeten verwijzen ondanks de achterliggende '/'. 

U kunt echter niet alle slashes negeren, zoals:

  1. De schuine streep tussen 'gebruiker' en 'instellingen', e, 'gebruiker/instellingen'.
  2. Ook moet u rekening houden met de '//' aan het begin van uw FQDN gevolgd door 'https'.

Dus je komt met een regel als: "Negeer alleen de schuine strepen naar voren gevolgd door lege ruimte".” en als je wilt, kun je die regel coderen met een reeks if-else-instructies. Maar dat wordt al snel omslachtig. Je kunt een functie schrijven met de tekst cleanUrl() die dit voor je kan inkapselen. Maar het universum zal binnenkort meer curveballs naar je gooien. Je zult al snel merken dat je functies schrijft voor cleanHeaders(), processLog(), etc. Of je kunt een reguliere expressie gebruiken wanneer er een patroon nodig is.

Standaard IO en bestanden

Voordat we ingaan op de details van reguliere expressies, is het de moeite waard om het model te noemen dat de meeste systemen hebben voor tekststromen. Hier is een korte (onvolledige) samenvatting ervan:

  1. Tekst wordt verwerkt als een (enkele) stroom karakters.
  2. Deze stream kan afkomstig zijn van een bestand met Unicode- of ASCII-tekst of van standaardinvoer (toetsenbord) of van een externe netwerkverbinding. Na verwerking, bijvoorbeeld door een regex-script, gaat de uitvoer naar een bestand of netwerkstream of naar de standaarduitvoer (e.g, console)
  3. De stream bestaat uit een of meer regels. Elke regel heeft nul of meer tekens gevolgd door een nieuwe regel.

Voor de eenvoud wil ik dat je je voorstelt dat een bestand is samengesteld uit regels die eindigen op een teken voor een nieuwe regel. We splitsen dit bestand op in afzonderlijke regels (of tekenreeksen) die elk eindigen met een nieuwe regel of een normaal teken (voor de laatste regel).

Regex en String

Een regex heeft niets speciaals te maken met bestanden. Stel je het voor als een zwarte doos die elke willekeurige string van elke (eindige) lengte als invoer kan nemen en zodra het het einde van deze string bereikt, kan het ofwel:

  1. Accepteer de string. Met andere woorden, de string wedstrijden de reguliere expressie (regex).
  2. Weiger de string, i.e, de string niet bij elkaar passen de reguliere expressie (regex).

Ondanks zijn zwarte doos-achtige aard, zal ik nog een paar beperkingen aan deze machine toevoegen. Een regex leest een string achtereenvolgens, van links naar rechts, en er wordt slechts één teken tegelijk gelezen. Dus een string “LinuxHint” met te lezen als:

'L"i"n"u"x"H"i"n"t' [Links naar rechts]

Laten we simpel beginnen

Het meest simplistische type regex zou zijn om te zoeken naar en overeenkomen met een tekenreeks 'C'. De reguliere expressie ervoor is gewoon 'C'. Vrij triviaal. De manier om het in Python te doen, zou vereisen dat je eerst de . importeert opnieuw module voor reguliere expressies.

>>> import re

We gebruiken dan de functie re.zoeken(patroon, touwtje) waar? patroon is onze reguliere expressie en draad in de invoerreeks waarbinnen we naar het patroon zoeken.

>>> opnieuw.search('C', 'Deze zin heeft een opzettelijke C')

De functie neemt het patroon 'C' op, zoekt ernaar in de invoerreeks en drukt de locatie af (span) waar het genoemde patroon wordt gevonden. Dit deel van de tekenreeks, deze subtekenreeks komt overeen met onze reguliere expressie. Als er geen dergelijke overeenkomst was gevonden, zou de uitvoer a . zijn Geen voorwerp.

Op dezelfde manier kunt u als volgt naar het patroon 'reguliere expressie' zoeken:

>>>re.search(“regular expression”,“We kunnen reguliere expressies gebruiken om patronen te zoeken.”)

opnieuw.zoeken() , opnieuw.match() en re.volledige wedstrijd()

Drie handige functies van de re-module zijn:

1.  opnieuw.zoeken(patroon, touwtje)

Dit retourneert de substring die overeenkomt met het patroon, zoals we hierboven hebben gezien. Als er geen match is gevonden dan Geen wordt geretourneerd. Als meerdere substrings voldoen aan een bepaald patroon, wordt alleen de eerste keer gerapporteerd.

2.  opnieuw.bij elkaar passen(patroon, touwtje)

Deze functie probeert het opgegeven patroon vanaf het begin van de string te matchen. Als het ergens halverwege een pauze tegenkomt, keert het terug Geen.

Bijvoorbeeld,

>>> opnieuw.match ("Joh", "John Doe")

Waar als de tekenreeks "Mijn naam is John Doe" geen overeenkomst is, en vandaar: Geen wordt geretourneerd.

>>> afdrukken (opnieuw.match ("Joh", "Mijn naam is John Doe"))
Geen

3.  opnieuw.volledige wedstrijd(patroon, touwtje)

Dit is strenger dan het bovenstaande en probeert een exacte overeenkomst te vinden met het patroon in de tekenreeks, anders wordt standaard Geen.

>>> afdrukken (opnieuw.volledige match ("Joh", "Joh"))

# Iets anders zal geen match zijn

Ik zal alleen de gebruiken opnieuw.zoeken() functie in de rest van dit artikel. Telkens wanneer ik zeg dat de regex deze tekenreeks accepteert, betekent dit dat athe opnieuw.zoeken() functie heeft een overeenkomende subtekenreeks in de invoertekenreeks gevonden en die geretourneerd, in plaats van Geenvoorwerp.

Speciale tekens

Reguliere expressies zoals 'John' en 'C' hebben niet veel nut. We hebben speciale tekens nodig die een specifieke betekenis hebben in de context van reguliere expressies. Hier zijn een paar voorbeelden:

    1. ^ - Dit komt overeen met het begin van een string. '^C' komt bijvoorbeeld overeen met alle tekenreeksen die beginnen met de letter C.
    2. $ - Dit komt overeen met het einde van de regel.
    3. . - De punt is om een ​​of meer tekens aan te geven, behalve de nieuwe regel.
    4. * - Dit is nul of meer tekens van wat eraan voorafging. Dus b* komt overeen met 0 of meer keren dat b . voorkomt. ab* komt alleen overeen met a, ab en a
    5. + - Dit is voor een of meer karakters van wat eraan voorafging. Dus b+ komt overeen met 1 of meer exemplaren van b. ab* komt alleen overeen met a, ab en a
    6. \ - Backslash wordt gebruikt als escape-reeks in de regexes. U wilt dus dat een reguliere expressie zoekt naar de letterlijke aanwezigheid van het dollarteken '$' in plaats van het einde van de regel. U kunt \$ in reguliere expressie schrijven.
    7. U kunt accolades gebruiken om het aantal herhalingen op te geven dat u wilt zien. Een patroon als ab10 betekent bijvoorbeeld dat de tekenreeks a gevolgd door 10 b overeenkomt met dit patroon. U kunt ook een reeks getallen opgeven, zoals b4,6 komt overeen met tekenreeksen met b die 4 tot 6 keer achter elkaar worden herhaald. Het patroon voor 4 of meer herhalingen zou slechts een volgkomma vereisen, zoals b4,
    8. Vierkante haken en reeks tekens. RE zoals [0-9] kan fungeren als een tijdelijke aanduiding voor elk cijfer tussen 0 en 9. Evenzo kunt u cijfers hebben tussen één en vijf [1-5] of om een ​​hoofdletter te gebruiken [A-Z] of voor elke letter van het alfabet, ongeacht of het hoofdletters of kleine letters zijn, gebruik [A-z].
      Elke tekenreeks van precies tien cijfers komt bijvoorbeeld overeen met de reguliere expressie [0-9]10, wat erg handig is als u telefoonnummers zoekt in een bepaalde tekenreeks.
    9. U kunt een OR-achtige verklaring maken met | teken waarbij een reguliere expressie bestaat uit twee of meer reguliere expressies, bijvoorbeeld A en B. De regex A|B is een overeenkomst als de invoertekenreeks ofwel een overeenkomst is voor reguliere expressie A of voor B.
    10. Je kunt verschillende regexes groeperen. De regex (A|B)C komt bijvoorbeeld overeen met regexen voor AC en

Er valt nog veel meer te bespreken, maar ik zou aanraden om gaandeweg te leren in plaats van je hersenen te overbelasten met veel obscure symbolen en randgevallen. Bij twijfel zijn de Python-documenten een grote hulp en nu weet je genoeg om de documenten gemakkelijk te volgen.

Praktische ervaring en referenties

Als je een visuele interpretatie van je regex wilt zien, ga dan naar Debuggex. Deze site genereert in realtime een weergave van uw regex en laat u deze testen aan de hand van verschillende invoerreeksen.

Om meer te weten te komen over het theoretische aspect van reguliere expressies kun je de eerste paar hoofdstukken van Inleiding tot de theorie van berekeningen door Michael Sipser bekijken. Het is heel gemakkelijk te volgen en toont het belang aan van reguliere expressies als een kernconcept van de berekening zelf!

Hoe de linker- en rechtermuisknop op Windows 10 pc te veranderen
Het is nogal een norm dat alle computermuisapparaten ergonomisch zijn ontworpen voor rechtshandige gebruikers. Maar er zijn muisapparaten beschikbaar ...
Emuleer muisklikken door te zweven met Clickless Mouse in Windows 10
Het gebruik van een muis of toetsenbord in de verkeerde houding of overmatig gebruik kan leiden tot veel gezondheidsproblemen, waaronder spanning, car...
Voeg muisbewegingen toe aan Windows 10 met deze gratis tools
In de afgelopen jaren zijn computers en besturingssystemen sterk geëvolueerd. Er was een tijd dat gebruikers opdrachten moesten gebruiken om door best...