Πώς να χρησιμοποιήσετε την ενότητα κανονικών εκφράσεων της Python re (match, search, sub, κ.λπ.)

Επιχείρηση

Για να εκτελέσουμε επεξεργασία κανονικών εκφράσεων στην Python, χρησιμοποιούμε την ενότητα re από την τυπική βιβλιοθήκη. Σας επιτρέπει να εξαγάγετε, να αντικαταστήσετε και να χωρίσετε συμβολοσειρές χρησιμοποιώντας πρότυπα κανονικών εκφράσεων.

Σε αυτή την ενότητα, θα εξηγήσουμε πρώτα τις λειτουργίες και τις μεθόδους της ενότητας re.

  • Σύνταξη μοτίβων κανονικής έκφρασης:compile()
  • αντικείμενο αντιστοίχισης
  • Ελέγξτε αν η αρχή της συμβολοσειράς ταιριάζει, εξάγετε:match()
  • Ελέγξτε για αγώνες που δεν περιορίζονται στην αρχή:search()
  • Ελέγξτε αν ολόκληρη η συμβολοσειρά ταιριάζει:fullmatch()
  • Λάβετε έναν κατάλογο όλων των ανταλλακτικών που ταιριάζουν:findall()
  • Λήψη όλων των ταιριαστών τμημάτων ως επαναλήπτη:finditer()
  • Αντικαταστήστε το αντίστοιχο εξάρτημα:sub(),subn()
  • Διαχωρισμός συμβολοσειρών με πρότυπα κανονικής έκφρασης:split()

Στη συνέχεια, θα εξηγήσω τους μετα-χαρακτήρες (ειδικούς χαρακτήρες) και τις ειδικές ακολουθίες των κανονικών εκφράσεων που μπορούν να χρησιμοποιηθούν στην ενότητα re. Βασικά, πρόκειται για την τυπική σύνταξη κανονικών εκφράσεων, αλλά να είστε προσεκτικοί με τον καθορισμό των σημαιών (ειδικά της re.ASCII).

  • Μεταχαρακτήρες κανονικών εκφράσεων, ειδικές ακολουθίες και προειδοποιήσεις στην Python
  • Ρύθμιση της σημαίας
    • Περιορίζεται σε χαρακτήρες ASCII:re.ASCII
    • Δεν λαμβάνεται υπόψη η πεζότητα:re.IGNORECASE
    • Ταιριάξτε την αρχή και το τέλος κάθε γραμμής:re.MULTILINE
    • Καθορισμός πολλαπλών σημαιών
  • Άπληστοι και μη άπληστοι αγώνες

Μεταγλώττιση του προτύπου κανονικής έκφρασης: compile()

Υπάρχουν δύο τρόποι για να εκτελέσετε την επεξεργασία κανονικών εκφράσεων στην ενότητα re.

Εκτέλεση με λειτουργία

Η πρώτη είναι μια συνάρτηση.re.match(),re.sub()Συναρτήσεις όπως αυτές είναι διαθέσιμες για την εκτέλεση εξαγωγής, αντικατάστασης και άλλων διεργασιών που χρησιμοποιούν πρότυπα κανονικών εκφράσεων.

Οι λεπτομέρειες των συναρτήσεων θα περιγραφούν αργότερα, αλλά σε όλες, το πρώτο όρισμα είναι η συμβολοσειρά του προτύπου κανονικής έκφρασης, ακολουθούμενη από τη συμβολοσειρά προς επεξεργασία κ.ο.κ. Για παράδειγμα, στην re.sub(), η οποία εκτελεί αντικατάσταση, το δεύτερο όρισμα είναι η συμβολοσειρά αντικατάστασης και το τρίτο όρισμα είναι η συμβολοσειρά προς επεξεργασία.

import re

s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'

m = re.match(r'([a-z]+)@([a-z]+)\.com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

result = re.sub(r'([a-z]+)@([a-z]+)\.com', 'new-address', s)
print(result)
# new-address, new-address, ccc@zzz.net

Σημειώστε ότι το [a-z] στο μοτίβο κανονικής έκφρασης σε αυτό το παράδειγμα σημαίνει οποιονδήποτε χαρακτήρα από το a έως το z (δηλαδή πεζό αλφάβητο) και το + σημαίνει επανάληψη του προηγούμενου μοτίβου (σε αυτή την περίπτωση [a-z]) μία ή περισσότερες φορές. Το [a-z]+ ταιριάζει με οποιαδήποτε συμβολοσειρά που επαναλαμβάνει έναν ή περισσότερους πεζούς αλφαβητικούς χαρακτήρες.

. είναι μετα-χαρακτήρας (χαρακτήρας με ειδική σημασία) και πρέπει να αποφεύγεται με backslash.

Δεδομένου ότι οι συμβολοσειρές προτύπων κανονικών εκφράσεων συχνά χρησιμοποιούν πολλές backslashes, είναι βολικό να χρησιμοποιείτε ακατέργαστες συμβολοσειρές όπως στο παράδειγμα.

Εκτελείται σε μια μέθοδο ενός αντικειμένου μοτίβου κανονικής έκφρασης

Ο δεύτερος τρόπος επεξεργασίας κανονικών εκφράσεων στην ενότητα re είναι η μέθοδος αντικειμένου μοτίβου κανονικών εκφράσεων.

Χρησιμοποιώντας την re.compile(), μπορείτε να μεταγλωττίσετε μια συμβολοσειρά προτύπου κανονικής έκφρασης για να δημιουργήσετε ένα αντικείμενο προτύπου κανονικής έκφρασης.

p = re.compile(r'([a-z]+)@([a-z]+)\.com')

print(p)
# re.compile('([a-z]+)@([a-z]+)\\.com')

print(type(p))
# <class 're.Pattern'>

re.match(),re.sub()Για παράδειγμα, η ίδια διαδικασία με αυτές τις συναρτήσεις μπορεί να εκτελεστεί ως μέθοδοι match(),sub() των αντικειμένων κανονικής έκφρασης.

m = p.match(s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

result = p.sub('new-address', s)
print(result)
# new-address, new-address, ccc@zzz.net

Όλες οι συναρτήσεις re.xxx() που περιγράφονται παρακάτω παρέχονται επίσης ως μέθοδοι του αντικειμένου κανονικής έκφρασης.

Εάν επαναλαμβάνετε μια διαδικασία που χρησιμοποιεί το ίδιο μοτίβο, είναι πιο αποδοτικό να δημιουργήσετε ένα αντικείμενο κανονικής έκφρασης με την re.compile() και να το χρησιμοποιήσετε τριγύρω.

Στον κώδικα του παρακάτω δείγματος, η συνάρτηση χρησιμοποιείται χωρίς μεταγλώττιση για λόγους ευκολίας, αλλά αν θέλετε να χρησιμοποιήσετε το ίδιο μοτίβο επανειλημμένα, συνιστάται να το μεταγλωττίσετε εκ των προτέρων και να το εκτελέσετε ως μέθοδο ενός αντικειμένου κανονικής έκφρασης.

αντικείμενο αντιστοίχισης

match(), search(), κ.λπ. επιστρέφουν ένα αντικείμενο match.

s = 'aaa@xxx.com'

m = re.match(r'[a-z]+@[a-z]+\.[a-z]+', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

print(type(m))
# <class 're.Match'>

Η αντιστοιχισμένη συμβολοσειρά και η θέση λαμβάνονται χρησιμοποιώντας τις ακόλουθες μεθόδους του αντικειμένου match.

  • Λάβετε την τοποθεσία του αγώνα:start(),end(),span()
  • Λήψη της συμβολοσειράς που ταιριάζει:group()
  • Λήψη της συμβολοσειράς για κάθε ομάδα:groups()
print(m.start())
# 0

print(m.end())
# 11

print(m.span())
# (0, 11)

print(m.group())
# aaa@xxx.com

Αν περικλείσετε ένα μέρος ενός προτύπου κανονικής έκφρασης σε μια συμβολοσειρά με παρενθέσεις(), το μέρος θα επεξεργαστεί ως ομάδα. Σε αυτή την περίπτωση, η συμβολοσειρά του μέρους που ταιριάζει με κάθε ομάδα στην groups() μπορεί να ληφθεί ως πλειάδα.

m = re.match(r'([a-z]+)@([a-z]+)\.([a-z]+)', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

print(m.groups())
# ('aaa', 'xxx', 'com')

Ελέγξτε αν η αρχή μιας συμβολοσειράς ταιριάζει, extract: match()

Η match() επιστρέφει ένα αντικείμενο match αν η αρχή της συμβολοσειράς ταιριάζει με το μοτίβο.

Όπως αναφέρθηκε παραπάνω, το αντικείμενο match μπορεί να χρησιμοποιηθεί για την εξαγωγή της υποσειράς που ταυτοποιήθηκε ή απλά για να ελέγξετε αν έγινε ταύτιση.

Η match() θα ελέγξει μόνο την αρχή. Εάν δεν υπάρχει κανένα ταιριαστό αλφαριθμητικό στην αρχή, επιστρέφει None.

s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'

m = re.match(r'[a-z]+@[a-z]+\.com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

m = re.match(r'[a-z]+@[a-z]+\.net', s)
print(m)
# None

Έλεγχος για αντιστοιχίες που δεν περιορίζονται στην αρχή, απόσπασμα: search()

Όπως και η match(), επιστρέφει ένα αντικείμενο match αν ταιριάζει.

Εάν υπάρχουν πολλαπλά τμήματα που ταιριάζουν, θα επιστραφεί μόνο το πρώτο τμήμα που ταιριάζει.

s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'

m = re.search(r'[a-z]+@[a-z]+\.net', s)
print(m)
# <re.Match object; span=(26, 37), match='ccc@zzz.net'>

m = re.search(r'[a-z]+@[a-z]+\.com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

Αν θέλετε να λάβετε όλα τα τμήματα που ταιριάζουν, χρησιμοποιήστε την findall() ή την finditer() όπως περιγράφεται παρακάτω.

Ελέγξτε αν ολόκληρη η συμβολοσειρά ταιριάζει: fullmatch()

Για να ελέγξετε αν ολόκληρη η συμβολοσειρά ταιριάζει με το μοτίβο κανονικής έκφρασης, χρησιμοποιήστε την fullmatch(). Αυτό είναι χρήσιμο, για παράδειγμα, για να ελέγξετε αν μια συμβολοσειρά είναι έγκυρη ως διεύθυνση ηλεκτρονικού ταχυδρομείου ή όχι.

Εάν ολόκληρη η συμβολοσειρά ταιριάζει, επιστρέφεται ένα αντικείμενο match.

s = 'aaa@xxx.com'

m = re.fullmatch(r'[a-z]+@[a-z]+\.com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

Εάν υπάρχουν τμήματα που δεν ταιριάζουν (μόνο μερικές αντιστοιχίες ή καθόλου αντιστοιχίες), επιστρέφεται το None.

s = '!!!aaa@xxx.com!!!'

m = re.fullmatch(r'[a-z]+@[a-z]+\.com', s)
print(m)
# None

Η fullmatch() προστέθηκε στην Python 3.4. Αν θέλετε να κάνετε το ίδιο σε προηγούμενες εκδόσεις, χρησιμοποιήστε την match() και έναν ταιριαστό μετα-χαρακτήρα $ στο τέλος. Αν ολόκληρη η συμβολοσειρά από την αρχή μέχρι το τέλος δεν ταιριάζει, επιστρέφει None.

s = '!!!aaa@xxx.com!!!'

m = re.match(r'[a-z]+@[a-z]+\.com$', s)
print(m)
# None

Λήψη μιας λίστας με όλα τα μέρη που ταιριάζουν: findall()

Η findall() επιστρέφει μια λίστα με όλες τις υποομάδες που ταιριάζουν. Σημειώστε ότι τα στοιχεία της λίστας δεν είναι αντικείμενα αντιστοίχισης αλλά συμβολοσειρές.

s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'

result = re.findall(r'[a-z]+@[a-z]+\.[a-z]+', s)
print(result)
# ['aaa@xxx.com', 'bbb@yyy.com', 'ccc@zzz.net']

Ο αριθμός των αντιστοιχισμένων τμημάτων μπορεί να ελεγχθεί χρησιμοποιώντας την ενσωματωμένη συνάρτηση len(), η οποία επιστρέφει τον αριθμό των στοιχείων της λίστας.

print(len(result))
# 3

Η ομαδοποίηση με παρενθέσεις() σε ένα μοτίβο κανονικής έκφρασης επιστρέφει μια λίστα πλειάδων των οποίων τα στοιχεία είναι οι συμβολοσειρές κάθε ομάδας. Αυτό είναι ισοδύναμο με την group() στο αντικείμενο match.

result = re.findall(r'([a-z]+)@([a-z]+)\.([a-z]+)', s)
print(result)
# [('aaa', 'xxx', 'com'), ('bbb', 'yyy', 'com'), ('ccc', 'zzz', 'net')]

Οι παρενθέσεις της ομάδας () μπορούν να είναι εμφωλευμένες, οπότε αν θέλετε να λάβετε και ολόκληρη την αντιστοίχιση, απλώς περικλείστε ολόκληρη την αντιστοίχιση σε παρενθέσεις ().

result = re.findall(r'(([a-z]+)@([a-z]+)\.([a-z]+))', s)
print(result)
# [('aaa@xxx.com', 'aaa', 'xxx', 'com'), ('bbb@yyy.com', 'bbb', 'yyy', 'com'), ('ccc@zzz.net', 'ccc', 'zzz', 'net')]

Εάν δεν βρεθεί καμία αντιστοιχία, επιστρέφεται μια κενή πλειάδα.

result = re.findall('[0-9]+', s)
print(result)
# []

Λήψη όλων των ταιριαστών τμημάτων ως επαναλήπτη: finditer()

Η finditer() επιστρέφει όλα τα ταιριαστά μέρη ως επαναλήπτη. Τα στοιχεία δεν είναι συμβολοσειρές όπως η findall(), αλλά αντικείμενα αντιστοίχισης, ώστε να μπορείτε να λάβετε τη θέση (δείκτη) των τμημάτων που ταιριάζουν.

Ο ίδιος ο επαναλήπτης δεν μπορεί να εκτυπωθεί με την print() για να λάβετε τα περιεχόμενά του. Αν χρησιμοποιήσετε την ενσωματωμένη συνάρτηση next() ή την εντολή for, μπορείτε να λάβετε τα περιεχόμενα ένα προς ένα.

s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'

result = re.finditer(r'[a-z]+@[a-z]+\.[a-z]+', s)
print(result)
# <callable_iterator object at 0x10b0efa90>

print(type(result))
# <class 'callable_iterator'>

for m in result:
    print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>
# <re.Match object; span=(13, 24), match='bbb@yyy.com'>
# <re.Match object; span=(26, 37), match='ccc@zzz.net'>

Μπορεί επίσης να μετατραπεί σε λίστα με την list().

l = list(re.finditer(r'[a-z]+@[a-z]+\.[a-z]+', s))
print(l)
# [<re.Match object; span=(0, 11), match='aaa@xxx.com'>, <re.Match object; span=(13, 24), match='bbb@yyy.com'>, <re.Match object; span=(26, 37), match='ccc@zzz.net'>]

print(l[0])
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

print(type(l[0]))
# <class 're.Match'>

print(l[0].span())
# (0, 11)

Αν θέλετε να λάβετε τη θέση όλων των τμημάτων που ταιριάζουν, ο συμβολισμός κατανόησης λίστας είναι πιο βολικός από τη list().

print([m.span() for m in re.finditer(r'[a-z]+@[a-z]+\.[a-z]+', s)])
# [(0, 11), (13, 24), (26, 37)]

Ο επαναλήπτης παίρνει τα στοιχεία με τη σειρά. Σημειώστε ότι αν προσπαθήσετε να αφαιρέσετε περισσότερα στοιχεία αφού φτάσετε στο τέλος, δεν θα μείνετε με τίποτα.

result = re.finditer(r'[a-z]+@[a-z]+\.[a-z]+', s)

for m in result:
    print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>
# <re.Match object; span=(13, 24), match='bbb@yyy.com'>
# <re.Match object; span=(26, 37), match='ccc@zzz.net'>

print(list(result))
# []

Αντικαταστήστε τα τμήματα που ταιριάζουν: sub(), subn()

Χρησιμοποιώντας την sub(), μπορείτε να αντικαταστήσετε το τμήμα που ταιριάζει με μια άλλη συμβολοσειρά. Το αλφαριθμητικό που αντικαταστάθηκε θα επιστραφεί.

s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'

result = re.sub(r'[a-z]+@[a-z]+\.com', 'new-address', s)
print(result)
# new-address, new-address, ccc@zzz.net

print(type(result))
# <class 'str'>

Κατά την ομαδοποίηση με παρένθεση(), η συμβολοσειρά που ταιριάζει μπορεί να χρησιμοποιηθεί στη συμβολοσειρά που αντικαθίσταται.

Από προεπιλογή, υποστηρίζονται τα εξής: για να διαφύγει η κάθετος δίαυλος.

\1Η πρώτη παρένθεση
\2Η δεύτερη παρένθεση
\3Η τρίτη παρένθεση
result = re.sub(r'([a-z]+)@([a-z]+)\.com', r'\1@\2.net', s)
print(result)
# aaa@xxx.net, bbb@yyy.net, ccc@zzz.net

?P<xxx>
Εάν ονομάσετε την ομάδα γράφοντας το όνομα αυτό στην αρχή των παρενθέσεων του μοτίβου κανονικής έκφρασης, μπορείτε να την καθορίσετε χρησιμοποιώντας το όνομα αντί για τον αριθμό, όπως φαίνεται παρακάτω.
\g<xxx>

result = re.sub(r'(?P<local>[a-z]+)@(?P<SLD>[a-z]+)\.com', r'\g<local>@\g<SLD>.net', s)
print(result)
# aaa@xxx.net, bbb@yyy.net, ccc@zzz.net

Το όρισμα count καθορίζει τον μέγιστο αριθμό αντικαταστάσεων. Θα αντικατασταθεί μόνο ο αριθμός από την αριστερή πλευρά.

result = re.sub(r'[a-z]+@[a-z]+\.com', 'new-address', s, count=1)
print(result)
# new-address, bbb@yyy.com, ccc@zzz.net

Η subn() επιστρέφει μια πλειάδα από την υποκατεστημένη συμβολοσειρά (ίδια με την τιμή επιστροφής της sub()) και τον αριθμό των υποκατεστημένων τμημάτων (ο αριθμός που ταιριάζει με το μοτίβο).

result = re.subn(r'[a-z]+@[a-z]+\.com', 'new-address', s)
print(result)
# ('new-address, new-address, ccc@zzz.net', 2)

Η μέθοδος προσδιορισμού των ορίων είναι η ίδια με την sub(). Μπορείτε να χρησιμοποιήσετε το μέρος που ομαδοποιείται με παρενθέσεις ή να καθορίσετε τον αριθμό των επιχειρημάτων.

result = re.subn(r'(?P<local>[a-z]+)@(?P<SLD>[a-z]+)\.com', r'\g<local>@\g<SLD>.net', s)
print(result)
# ('aaa@xxx.net, bbb@yyy.net, ccc@zzz.net', 2)

result = re.subn(r'[a-z]+@[a-z]+\.com', 'new-address', s, count=1)
print(result)
# ('new-address, bbb@yyy.com, ccc@zzz.net', 1)

Διαχωρισμός συμβολοσειρών με μοτίβα κανονικής έκφρασης: split()

Η split() χωρίζει το αλφαριθμητικό στο τμήμα που ταιριάζει με το μοτίβο και το επιστρέφει ως λίστα.

Σημειώστε ότι η πρώτη και η τελευταία αντιστοιχία θα περιέχουν κενές συμβολοσειρές στην αρχή και στο τέλος της προκύπτουσας λίστας.

s = '111aaa222bbb333'

result = re.split('[a-z]+', s)
print(result)
# ['111', '222', '333']

result = re.split('[0-9]+', s)
print(result)
# ['', 'aaa', 'bbb', '']

Το όρισμα maxsplit καθορίζει τον μέγιστο αριθμό διαχωρισμών (τεμαχίων). Μόνο η μέτρηση από την αριστερή πλευρά θα διαχωριστεί.

result = re.split('[a-z]+', s, 1)
print(result)
# ['111', '222bbb333']

Μεταχαρακτήρες κανονικών εκφράσεων, ειδικές ακολουθίες και προειδοποιήσεις στην Python

Οι κύριοι μετα-χαρακτήρες κανονικών εκφράσεων (ειδικοί χαρακτήρες) και οι ειδικές ακολουθίες που μπορούν να χρησιμοποιηθούν στην ενότητα Python 3 re είναι οι εξής

metacharacterπεριεχόμενα
.Οποιοσδήποτε μεμονωμένος χαρακτήρας εκτός της νέας γραμμής (συμπεριλαμβανομένης της νέας γραμμής με τη σημαία DOTALL)
^Η αρχή της συμβολοσειράς (ταιριάζει επίσης με την αρχή κάθε γραμμής με τη σημαία MULTILINE)
$Το τέλος της συμβολοσειράς (ταιριάζει επίσης με το τέλος κάθε γραμμής με τη σημαία MULTILINE)
*Επαναλάβετε το προηγούμενο μοτίβο περισσότερες από 0 φορές
+Επαναλάβετε το προηγούμενο μοτίβο τουλάχιστον μία φορά.
?Επαναλάβετε το προηγούμενο μοτίβο 0 ή 1 φορά
{m}Επαναλάβετε το προηγούμενο μοτίβο m φορές
{m, n}Το τελευταίο μοτίβο.m~nεπανάληψη
[]Ένα σύνολο χαρακτήρων[]Ταιριάζει με οποιονδήποτε από αυτούς τους χαρακτήρες
|ΉA|BΤαιριάζει είτε με το μοτίβο Α είτε με το μοτίβο Β
ειδική ακολουθίαπεριεχόμενα
\dΔεκαδικοί αριθμοί Unicode (περιορίζονται σε αριθμούς ASCII με τη σημαία ASCII)
\D\dΕννοώντας το αντίθετο από αυτό.
\sχαρακτήρες κενών διαστημάτων Unicode (περιορίζονται σε χαρακτήρες κενών διαστημάτων ASCII με τη σημαία ASCII)
\S\sΕννοώντας το αντίθετο από αυτό.
\wΧαρακτήρες λέξης Unicode και υπογράμμιση (περιορίζονται σε αλφαριθμητικούς χαρακτήρες ASCII και υπογράμμιση από τη σημαία ASCII)
\W\wΕννοώντας το αντίθετο από αυτό.

Δεν παρατίθενται όλες σε αυτόν τον πίνακα. Ανατρέξτε στην επίσημη τεκμηρίωση για μια πλήρη λίστα.

Σημειώστε επίσης ότι ορισμένες από τις έννοιες είναι διαφορετικές στην Python 2.

Ρύθμιση της σημαίας

Όπως φαίνεται στον παραπάνω πίνακα, ορισμένοι μετα-χαρακτήρες και ειδικές ακολουθίες αλλάζουν τον τρόπο λειτουργίας τους ανάλογα με τη σημαία.

Εδώ καλύπτονται μόνο οι κύριες σημαίες. Δείτε την επίσημη τεκμηρίωση για τα υπόλοιπα.

Περιορίζεται σε χαρακτήρες ASCII: re.ASCII

\wΑυτό θα ταιριάξει επίσης με double-byte kanji, αλφαριθμητικούς χαρακτήρες κ.λπ. από προεπιλογή για συμβολοσειρές Python 3. Δεν είναι ισοδύναμη με την ακόλουθη επειδή δεν είναι μια τυπική κανονική έκφραση.[a-zA-Z0-9_]

m = re.match(r'\w+', '漢字ABC123')
print(m)
# <re.Match object; span=(0, 11), match='漢字ABC123'>

m = re.match('[a-zA-Z0-9_]+', '漢字ABC123')
print(m)
# None

Εάν καθορίσετε re.ASCII για τις σημαίες ορίσματος σε κάθε συνάρτηση ή προσθέσετε την ακόλουθη inline σημαία στην αρχή της συμβολοσειράς προτύπων κανονικής έκφρασης, θα ταιριάζει μόνο με χαρακτήρες ASCII (δεν θα ταιριάζει με ιαπωνικούς χαρακτήρες διπλού byte, αλφαριθμητικούς χαρακτήρες κ.λπ.).
(?a)
Στην περίπτωση αυτή, τα δύο ακόλουθα είναι ισοδύναμα.
\w=[a-zA-Z0-9_]

m = re.match(r'\w+', '漢字ABC123', flags=re.ASCII)
print(m)
# None

m = re.match(r'(?a)\w+', '漢字ABC123')
print(m)
# None

Το ίδιο ισχύει και κατά τη μεταγλώττιση με την re.compile(). Χρησιμοποιήστε το όρισμα flags ή inline flags.

p = re.compile(r'\w+', flags=re.ASCII)
print(p)
# re.compile('\\w+', re.ASCII)

print(p.match('漢字ABC123'))
# None

p = re.compile(r'(?a)\w+')
print(p)
# re.compile('(?a)\\w+', re.ASCII)

print(p.match('漢字ABC123'))
# None

Το ASCII είναι επίσης διαθέσιμο ως σύντομη μορφή re. A.

print(re.ASCII is re.A)
# True

\W, το αντίθετο του \W, επηρεάζεται επίσης από τις σημαίες re.ASCII και inline.

m = re.match(r'\W+', '漢字ABC123')
print(m)
# None

m = re.match(r'\W+', '漢字ABC123', flags=re.ASCII)
print(m)
# <re.Match object; span=(0, 11), match='漢字ABC123'>

Όπως και με την \w, οι ακόλουθες δύο αντιστοιχούν τόσο σε χαρακτήρες μονών όσο και σε χαρακτήρες διπλών byte από προεπιλογή, αλλά περιορίζονται σε χαρακτήρες μονών byte αν καθοριστούν οι σημαίες re.ASCII ή inline.

  • Ταιριάξτε τους αριθμούς\d
  • Ταιριάζει με κενό χώρο\s
  • Ταιριάζει με μη αριθμούς\D
  • Ταιριάζει με οποιοδήποτε μη κενό διάστημα.\S
m = re.match(r'\d+', '123')
print(m)
# <re.Match object; span=(0, 3), match='123'>

m = re.match(r'\d+', '123')
print(m)
# <re.Match object; span=(0, 3), match='123'>

m = re.match(r'\d+', '123', flags=re.ASCII)
print(m)
# <re.Match object; span=(0, 3), match='123'>

m = re.match(r'\d+', '123', flags=re.ASCII)
print(m)
# None

m = re.match(r'\s+', ' ')  # full-width space
print(m)
# <re.Match object; span=(0, 1), match='\u3000'>

m = re.match(r'\s+', ' ', flags=re.ASCII)
print(m)
# None

Δεν λαμβάνεται υπόψη η πεζότητα:re.IGNORECASE

Από προεπιλογή, είναι ευαίσθητη στην πεζότητα. Για να ταιριάξετε και τα δύο, πρέπει να συμπεριλάβετε τόσο κεφαλαία όσο και πεζά γράμματα στο μοτίβο.

re.IGNORECASEΕάν αυτό έχει καθοριστεί, θα γίνει αντιστοίχιση χωρίς ευαισθησία στην πεζότητα. Ισοδύναμο με τη σημαία i στις τυπικές κανονικές εκφράσεις.

m = re.match('[a-zA-Z]+', 'abcABC')
print(m)
# <re.Match object; span=(0, 6), match='abcABC'>

m = re.match('[a-z]+', 'abcABC', flags=re.IGNORECASE)
print(m)
# <re.Match object; span=(0, 6), match='abcABC'>

m = re.match('[A-Z]+', 'abcABC', flags=re.IGNORECASE)
print(m)
# <re.Match object; span=(0, 6), match='abcABC'>

Μπορείτε να χρησιμοποιήσετε το less than ή το equal to.

  • σημαία γραμμής(?i)
  • συντομογραφίαre.I

Ταιριάξτε την αρχή και το τέλος κάθε γραμμής:re.MULTILINE

^Οι μετα-χαρακτήρες αυτής της κανονικής έκφρασης ταιριάζουν με την αρχή της συμβολοσειράς.

Από προεπιλογή, ταιριάζει μόνο η αρχή ολόκληρης της συμβολοσειράς, αλλά το παρακάτω θα ταιριάζει και με την αρχή κάθε γραμμής. Ισοδύναμο με τη σημαία m στις τυπικές κανονικές εκφράσεις.
re.MULTILINE

s = '''aaa-xxx
bbb-yyy
ccc-zzz'''

print(s)
# aaa-xxx
# bbb-yyy
# ccc-zzz

result = re.findall('[a-z]+', s)
print(result)
# ['aaa', 'xxx', 'bbb', 'yyy', 'ccc', 'zzz']

result = re.findall('^[a-z]+', s)
print(result)
# ['aaa']

result = re.findall('^[a-z]+', s, flags=re.MULTILINE)
print(result)
# ['aaa', 'bbb', 'ccc']

$Ταιριάζει με το τέλος της συμβολοσειράς. Από προεπιλογή, ταιριάζει μόνο το τέλος ολόκληρης της συμβολοσειράς.
re.MULTILINEΑν το καθορίσετε αυτό, θα ταιριάζει επίσης με το τέλος κάθε γραμμής.

result = re.findall('[a-z]+$', s)
print(result)
# ['zzz']

result = re.findall('[a-z]+$', s, flags=re.MULTILINE)
print(result)
# ['xxx', 'yyy', 'zzz']

Μπορείτε να χρησιμοποιήσετε το less than ή το equal to.

  • σημαία γραμμής(?m)
  • συντομογραφίαre.M

Καθορισμός πολλαπλών σημαιών

|Αν θέλετε να ενεργοποιήσετε πολλές σημαίες ταυτόχρονα, χρησιμοποιήστε αυτό. Στην περίπτωση των σημαιών γραμμής, κάθε χαρακτήρας πρέπει να ακολουθείται από ένα γράμμα, όπως φαίνεται παρακάτω.
(?am)

s = '''aaa-xxx
漢漢漢-字字字
bbb-zzz'''

print(s)
# aaa-xxx
# 漢漢漢-字字字
# bbb-zzz

result = re.findall(r'^\w+', s, flags=re.M)
print(result)
# ['aaa', '漢漢漢', 'bbb']

result = re.findall(r'^\w+', s, flags=re.M | re.A)
print(result)
# ['aaa', 'bbb']

result = re.findall(r'(?am)^\w+', s)
print(result)
# ['aaa', 'bbb']

Άπληστοι και μη άπληστοι αγώνες

Αυτό είναι ένα γενικό πρόβλημα με τις κανονικές εκφράσεις, όχι μόνο ένα πρόβλημα με την Python, αλλά θα γράψω γι' αυτό επειδή τείνει να με βάζει σε μπελάδες.

Από προεπιλογή, το παρακάτω είναι ένα άπληστο ταίριασμα, το οποίο ταιριάζει με τη μεγαλύτερη δυνατή συμβολοσειρά.

  • *
  • +
  • ?
s = 'aaa@xxx.com, bbb@yyy.com'

m = re.match(r'.+com', s)
print(m)
# <re.Match object; span=(0, 24), match='aaa@xxx.com, bbb@yyy.com'>

print(m.group())
# aaa@xxx.com, bbb@yyy.com

Το ? μετά από αυτό θα έχει ως αποτέλεσμα ένα μη άπληστο, ελάχιστο ταίριασμα, που ταιριάζει με τη συντομότερη δυνατή συμβολοσειρά.

  • *?
  • +?
  • ??
m = re.match(r'.+?com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

print(m.group())
# aaa@xxx.com

Σημειώστε ότι το προεπιλεγμένο άπληστο ταίριασμα μπορεί να ταιριάζει με απροσδόκητες συμβολοσειρές.

Copied title and URL