Θετική και αρνητική προβολή στις κανονικές εκφράσεις της Python

Μερικές φορές χρειάζεται να λύσουμε ένα πρόβλημα του τύπου: βρες τη συμβολοσειρά 'aaa' και άλλαξέ την σε '!', αλλά μόνο αν μετά από την 'aaa' ακολουθεί 'x', ενώ ο ίδιος ο 'x' να μην αντικατασταθεί. Αν προσπαθήσουμε να λύσουμε το πρόβλημε 'κατευθείαν', δεν θα τα καταφέρουμε:

pythontxt = 'aaax baaa'
res = re.sub('aaax', '!', txt)

print(res) # θα τυπώσει '! baaa', αλλά θέλαμε '!x baaa'

Προβολή μπροστά

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

Αυτές οι αγκύλες ονομάζονται θετική προβολή μπροστά. Θετική - γιατί ο 'x' (στην περίπτωσή μας) πρέπει να υπάρχει - μόνο τότε θα γίνει η αντικατάσταση.

Ας εφαρμόσουμε αυτές τις αγκύλες για να λύσουμε το πρόβλημά μας:

pythontxt = 'aaax baaa'
res = re.sub('aaa(?=x)', '!', txt)
print(res) # θα τυπώσει '!x aaab

Υπάρχει και αρνητική προβολή μπροστά - (?! ) - αυτή, αντίθετα, λέει ότι κάτι δεν πρέπει να υπάρχει. Στο επόμενο παράδειγμα, η αντικατάσταση θα γίνει, μόνο αν μετά από την 'aaa' ΔΕΝ ακολουθεί 'x':

pythontxt = 'aaax aaab'
res = re.sub('aaa(?!x)', '!', txt)

print(res) # θα τυπώσει 'aaax !b'

Προβολή πίσω

Με παρόμοιο τρόπο υπάρχει θετική προβολή πίσω - (?<= ). Στο επόμενο παράδειγμα η αντικατάσταση θα γίνει, μόνο αν πριν από την 'aaa' υπάρχει 'x':

pythontxt = 'xaaa'
res = re.sub('(?<=x)aaa', '!', txt)

print(res) # θα τυπώσει 'x!'

Και υπάρχει επίσης αρνητική προβολή πίσω - (?<! ). Στο επόμενο παράδειγμα η αντικατάσταση θα γίνει, μόνο αν πριν από την 'aaa' ΔΕΝ υπάρχει 'x':

pythontxt = 'baaa'
res = re.sub('(?<!x)aaa', '!', txt)

print(res) # θα τυπώσει 'b!'

Πρακτικά προβλήματα

Задание 1

Δίνεται μια συμβολοσειρά, που περιέχει ονόματα συναρτήσεων:

pythontxt = 'func1() func2() func3()'

Πάρτε έναν πίνακα με τα ονόματα των συναρτήσεων από τη συμβολοσειρά.

Задание 2

Δίνεται μια συμβολοσειρά με μια ετικέτα:

pythontxt = '<a href="" class="eee" id="zzz">'

Πάρτε έναν πίνακα με τα ονόματα των χαρακτηριστικών αυτής της ετικέτας.

Задание 3

Δίνεται μια συμβολοσειρά με μεταβλητές:

pythontxt = '$aaa $bbb $ccc xxxx'

Πάρτε τις υποσυμβολοσειρές, πριν από τις οποίες υπάρχει το σύμβολο του δολαρίου.