Περιορισμός της απληστίας στις κανονικές εκφράσεις στην Python
Οι κανονικές εκφράσεις είναι από προεπιλογή άπληστες. Αυτό σημαίνει ότι καταλαμβάνουν το μέγιστο δυνατό αριθμό χαρακτήρων. Ας το εξετάσουμε με ένα παράδειγμα. Ας υποθέσουμε ότι έχουμε την ακόλουθη συμβολοσειρά:
txt = 'aeeex zzz x kkk'
Σε αυτή τη συμβολοσειρά θέλουμε να βρούμε την υποσυμβολοσειρά
'aeeex' σύμφωνα με το ακόλουθο μοτίβο:
το γράμμα 'a', ακολουθούμενο από οποιονδήποτε χαρακτήρα
μία ή περισσότερες φορές, ακολουθούμενο από το γράμμα 'x':
res = re.sub('a.+x', '!', txt)
print(res)
Παρόλο που θέλουμε να πάρουμε τη συμβολοσειρά '! zzz
x kkk', θα εκτυπωθεί η συμβολοσειρά '! kkk'.
Ο λόγος είναι ότι η κανονική μας έκφραση αναζητά
όλους τους χαρακτήρες από το γράμμα 'a' μέχρι το γράμμα
'x'. Αλλά στη συμβολοσειρά μας υπάρχουν δύο γράμματα
'x'! Λόγω της απληστίας, η κανονική έκφραση
αναζητά μέχρι το τελευταίο 'x',
καταλαμβάνοντας έτσι περισσότερα από αυτά που χρειαζόμασταν.
Φυσικά, συχνά αυτή η συμπεριφορά είναι ακριβώς αυτή που
χρειαζόμαστε. Αλλά σε αυτή τη συγκεκριμένη περίπτωση πρέπει
να απενεργοποιήσουμε την απληστία και να πούμε στην κανονική έκφραση
να αναζητήσει μέχρι το πρώτο 'x'. Σε αυτή
την περίπτωση, πρέπει να βάλουμε ένα ερωτηματικό μετά τον τελεστή επανάληψης:
res = re.sub('a.+?x', '!', txt)
print(res) # θα εκτυπώσει τη συμβολοσειρά '! zzz x kkk'
Η απληστία μπορεί να περιοριστεί σε όλους τους τελεστές
επανάληψης: τόσο στον *, όσο και στον ?, και
στον {} - έτσι: *?, ??
και {}?.
Δίνεται η συμβολοσειρά:
txt = 'aba accca azzza wwwwa'
Γράψτε μια κανονική έκφραση που θα βρει όλες τις
συμβολοσειρές στα άκρα των οποίων βρίσκονται τα γράμματα
'a', και θα αντικαταστήσει καθεμία από αυτές με
'!'. Μεταξύ των γραμμάτων 'a' μπορεί
να υπάρχει οποιοσδήποτε χαρακτήρας (εκτός από το 'a').