Ομάδες (Capturing Groups) σε Regular Expressions στην PHP
Το περιεχόμενο των ομάδων (capturing groups) δεν είναι διαθέσιμο μόνο στη γραμμή αντικατάστασης, αλλά και στο ίδιο το κανονικό έκφραση: μπορούμε να βάλουμε κάτι σε μια ομάδα, και στη συνέχεια ακριβώς μέσα στο κανονικό έκφραση να πούμε ότι εδώ πρέπει να βρίσκεται το περιεχόμενο αυτής της ομάδας.
Το περιεχόμενο των ομάδων είναι διαθέσιμο μέσω των αριθμών τους,
πριν από τους οποίους υπάρχει μια ανάστροφη πλάγια γραμμή (backslash). Για παράδειγμα,
η μηδενική ομάδα θα είναι διαθέσιμη έτσι: \0,
η πρώτη ομάδα έτσι - \1, η δεύτερη
- \2 και ούτω καθεξής.
Είμαι βέβαιος ότι όλα τα παραπάνω γραπτά είναι ακόμα πολύ ασαφή για εσάς. Αυτό δεν προκαλεί έκπληξη, αφού οι ομάδες (capturing groups) είναι το πιο δυσνόητο σημείο των κανονικών εκφράσεων. Ας τα καταλάβουμε με παραδείγματα.
Παράδειγμα
Ας υποθέσουμε ότι έχουμε την ακόλουθη συμβολοσειρά:
<?php
$str = 'aa bb cd ef';
?>
Ας βρούμε σε αυτήν όλα τα σημεία στα οποία υπάρχουν δύο όμοια γράμματα στη σειρά. Για να λύσουμε το πρόβλημα, θα ψάξουμε για οποιοδήποτε γράμμα, θα το βάλουμε σε μια ομάδα, και στη συνέχεια θα ελέγξουμε αν το επόμενο σύμβολο είναι το περιεχόμενο αυτής της ομάδας:
<?php
$res = preg_replace('#([a-z])\1#', '!', $str);
?>
Ως αποτέλεσμα, στη μεταβλητή θα γραφτεί το ακόλουθο:
'! ! cd ef'
Παράδειγμα
Ας υποθέσουμε ότι έχουμε την ακόλουθη συμβολοσειρά:
<?php
$str = 'asxca buzxb csgd';
?>
Ας βρούμε σε αυτήν όλες τις λέξεις στις οποίες το πρώτο και το τελευταίο γράμμα είναι ίδια. Για να λύσουμε το πρόβλημα, θα γράψουμε το ακόλουθο μοτίβο: γράμμα, στη συνέχεια ένα ή περισσότερα γράμματα, και μετά το ίδιο γράμμα με το πρώτο:
<?php
$res = preg_replace('#([a-z])[a-z]+\1#', '!', $str);
?>
Ως αποτέλεσμα, στη μεταβλητή θα γραφτεί το ακόλουθο:
'! ! csgd'
Παράδειγμα
Αντί για \1 μπορείτε να γράψετε \g1:
<?php
$res = preg_replace('#([a-z])[a-z]+\g1#', '!', $str);
?>
Παράδειγμα
Μπορείτε επίσης να γράψετε \g{1}:
<?php
$res = preg_replace('#([a-z])[a-z]+\g{1}#', '!', $str);
?>
Παράδειγμα
Στα άγκιστρα μπορούν να καθοριστούν αρνητικοί αριθμοί. Σε αυτήν την περίπτωση, οι ομάδες θα μετρώνται από το τέλος:
<?php
$res = preg_replace('#([a-z])([a-z])\g{-2}#', '!', $str);
?>
Πρακτικές Ασκήσεις
Δίνεται η συμβολοσειρά:
<?php
$str = 'aaa bbb ccc xyz';
?>
Βρείτε όλες τις υποσυμβολοσειρές στις οποίες υπάρχουν τρία ίδια γράμματα στη σειρά.
Δίνεται η συμβολοσειρά:
<?php
$str = 'a aa aaa abab bbbb';
?>
Βρείτε όλες τις υποσυμβολοσειρές στις οποίες υπάρχουν δύο ή περισσότερα ίδια γράμματα στη σειρά.
Δίνεται η συμβολοσειρά:
<?php
$str = 'aaa aaa bbb bbb ccc ddd';
?>
Βρείτε όλες τις υποσυμβολοσειρές στις οποίες υπάρχουν δύο ίδιες λέξεις στη σειρά.