This shows you the differences between two versions of the page.
|
java:regular_expr [2019/03/14 10:08] gthanos created |
java:regular_expr [2021/03/10 18:32] |
||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ====== Regular Expressions ====== | ||
| - | |||
| - | Τα regular expressions είναι αλφαριθμητικά μέσω των οποίων μπορούμε να περιγράψουμε πρότυπα ταιριάσματος μέσα σε μία αλληλουχία χαρακτήρων (string). Τα regular-expressions αποτελούν ειδική γλώσσα η οποία προτυποποιήθηκε από τον Αμερικανό μαθηματικό [[wp> | ||
| - | ===== Οι κλάσης java.util.regex.Pattern & java.util.regex.Matcher ===== | ||
| - | |||
| - | Η Java υλοποιεί τα regular-expressions μέσω του πακέτου [[http:// | ||
| - | |||
| - | * [[http:// | ||
| - | * [[http:// | ||
| - | |||
| - | Η μορφή ενός προγράμματος που χρησιμοποιεί τις παραπάνω κλάσεις είναι η εξής: | ||
| - | <code java> | ||
| - | Pattern p = Pattern.compile(" | ||
| - | Matcher m = p.matcher(" | ||
| - | boolean b = m.matches(); | ||
| - | while(m.find()) { | ||
| - | String str = m.group(); | ||
| - | int startIndex = m.start(); | ||
| - | int endIndex = m.end(); | ||
| - | System.out.print(" | ||
| - | System.out.print(", | ||
| - | System.out.println(" | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | Το παραπάνω πρόγραμμα ορίζει το //pattern// **ένα ή περισσότερα a ακολουθούμενα από ένα b**. Τα ταιριάσματα μέσα στο string **aabhelloabworldaab** είναι τα εξής: | ||
| - | * **<color red> | ||
| - | * **aabhello< | ||
| - | * **aabhelloabworld< | ||
| - | |||
| - | Η κλάση [[http:// | ||
| - | * Η μέθοδος [[http:// | ||
| - | * Η μέθοδος [[http:// | ||
| - | * Η μέθοδοι [[http:// | ||
| - | |||
| - | ==== Παράδειγμα | ||
| - | |||
| - | <code java Regexp.java> | ||
| - | import java.util.regex.*; | ||
| - | |||
| - | public class Regexp { | ||
| - | public static void main(String []args) { | ||
| - | String input = "I allocated room for my cat"; | ||
| - | | ||
| - | // βρες όλες τις αλληλουχίες χαρακτήρων cat μέσα στο αλφαριθμητικό. | ||
| - | Pattern p = Pattern.compile(" | ||
| - | Matcher m = p.matcher(input); | ||
| - | while(m.find()) { | ||
| - | System.out.println(input.substring(0, | ||
| - | } | ||
| - | } | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | |||
| - | ===== Πρότυπα ταιριάσματος ===== | ||
| - | |||
| - | Με βάση το πρότυπο των regular-expressions η Java ορίζει τα παρακάτω μοτίβα ταιριάσματος. | ||
| - | |||
| - | ==== Ταιριάσματα χαρακτήρων ==== | ||
| - | |||
| - | === Μοναδικοί χαρακτήρες === | ||
| - | |||
| - | < | ||
| - | a Ο χαρακτήρας a (αφορά όλους τους μη ειδικούς χαρακτήρες) | ||
| - | \\ Ο χαρακτήρας backslash (escaped by an extra \ character) | ||
| - | \t Ο χαρακτήρας tab (' | ||
| - | \n Ο χαρακτήρας newline (line feed) (' | ||
| - | \r Ο χαρακτήρας carriage-return (' | ||
| - | \f Ο χαρακτήρας form-feed (' | ||
| - | \xhh Ο χαρακτήρας 0xhh | ||
| - | \uhhhh Ο χαρακτήρας 0xhhhh | ||
| - | </ | ||
| - | |||
| - | <code java Regexp.java> | ||
| - | import java.util.regex.*; | ||
| - | |||
| - | public class Regexp { | ||
| - | public static void main(String []args) { | ||
| - | String input = "I allocated \\ room \nfor \t my cat\\"; | ||
| - | System.out.println(" | ||
| - | | ||
| - | // βρες όλους τους χαρακτήρες TAB ή χαρακτήρες αλλαγής γραμμής \n | ||
| - | // ή χαρακτήρες \ (backslash) | ||
| - | Pattern p = Pattern.compile(" | ||
| - | Matcher m = p.matcher(input); | ||
| - | while(m.find()) { | ||
| - | System.out.println(input.substring(0, | ||
| - | } | ||
| - | } | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | === Ομάδες χαρακτήρων === | ||
| - | |||
| - | < | ||
| - | [abc] Οι χαρακτήρες a ή b ή c | ||
| - | [^abc] Οποιοσδήποτε χαρακτήρας εκτός των a, b, c (άρνηση) | ||
| - | [a-zA-Z] a έως z ή A έως Z | ||
| - | [a-d[m-p]] a έως d ή m έως p: [a-dm-p] (ένωση δύο συνόλων χαρακτήρων) | ||
| - | [a-z&& | ||
| - | [a-z&& | ||
| - | [a-z&& | ||
| - | </ | ||
| - | |||
| - | <code java Regexp.java> | ||
| - | import java.util.regex.*; | ||
| - | |||
| - | public class Regexp { | ||
| - | public static void main(String []args) { | ||
| - | String input = "I allocated room \nfor \t my cat"; | ||
| - | | ||
| - | Pattern p = Pattern.compile(" | ||
| - | Matcher m = p.matcher(input); | ||
| - | while(m.find()) { | ||
| - | System.out.println(" | ||
| - | } | ||
| - | } | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | == Συντομογραφίες ομάδων χαρακτήρων == | ||
| - | |||
| - | < | ||
| - | . Οποιοσδήποτε χαρακτήρας (may or may not match line terminators) | ||
| - | \d ψηφίο: | ||
| - | \D Μη ψηφίο: [^0-9] | ||
| - | \h Οριζόντιος κενός χαρακτήρας (εξαιρούνται χαρακτήρες αλλαγής γραμμής): | ||
| - | \H Μη οριζόντιος κενός χαρακτήρας: | ||
| - | \s Κενός χαρακτήρας: | ||
| - | \S Μη κενός χαρακτήρας: | ||
| - | \v Χαρακτήρας αλλαγής γραμμής: | ||
| - | \V Εξαιρούνται χαρακτήρες αλλαγής γραμμής: | ||
| - | \w Χαρακτήρας λέξης: [a-zA-Z_0-9] | ||
| - | \W Μη χαρακτήρας λέξης: [^\w] | ||
| - | </ | ||
| - | |||
| - | <code java Regexp.java> | ||
| - | import java.util.regex.*; | ||
| - | |||
| - | public class Regexp { | ||
| - | public static void main(String []args) { | ||
| - | String input = "Ι ate 10\tpieces\tof\tdark\tchocolate."; | ||
| - | | ||
| - | // βρες όλα τα ψηφία που ακολουθούνται από κενούς χαρακτήρες | ||
| - | Pattern p = Pattern.compile(" | ||
| - | Matcher m = p.matcher(input); | ||
| - | while(m.find()) { | ||
| - | System.out.println(" | ||
| - | } | ||
| - | } | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | == Συντομογραφίες POSIX == | ||
| - | |||
| - | < | ||
| - | \p{Lower} A lower-case alphabetic character: [a-z] | ||
| - | \p{Upper} An upper-case alphabetic character: | ||
| - | \p{ASCII} All ASCII: | ||
| - | \p{Alpha} An alphabetic character: | ||
| - | \p{Digit} A decimal digit: [0-9] | ||
| - | \p{Alnum} An alphanumeric character: | ||
| - | \p{Punct} Punctuation: | ||
| - | \p{Graph} A visible character: [\p{Alnum}\p{Punct}] | ||
| - | \p{Print} A printable character: [\p{Graph}\x20] | ||
| - | \p{Blank} A space or a tab: [ \t] | ||
| - | \p{Cntrl} A control character: [\x00-\x1F\x7F] | ||
| - | \p{XDigit} A hexadecimal digit: [0-9a-fA-F] | ||
| - | \p{Space} A whitespace character: [ \t\n\x0B\f\r] | ||
| - | </ | ||
| - | |||
| - | <code java Regexp.java> | ||
| - | import java.util.regex.*; | ||
| - | |||
| - | public class Regexp { | ||
| - | public static void main(String []args) { | ||
| - | String input = "- How are you today?\n - Fine! Thank you.\n - You 're welcome."; | ||
| - | | ||
| - | // βρες όλα τα σημεία στίξης !"# | ||
| - | Pattern p = Pattern.compile(" | ||
| - | Matcher m = p.matcher(input); | ||
| - | while(m.find()) { | ||
| - | System.out.println(" | ||
| - | } | ||
| - | } | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | === Χαρακτήρες προσιορισμού ορίων === | ||
| - | |||
| - | < | ||
| - | ^ Προσδιορίζει την αρχή της γραμμής | ||
| - | $ Προσδιορίζει το τέλος της γραμμής | ||
| - | \b (word boundary) Προσδιορίζει τον χαρακτήρα πριν από την αρχή ή το τέλος μίας λέξης | ||
| - | \B A non-word boundary | ||
| - | </ | ||
| - | |||
| - | <code java Regexp.java> | ||
| - | import java.util.regex.*; | ||
| - | |||
| - | public class Regexp { | ||
| - | public static void main(String []args) { | ||
| - | String input = "- How are you today?\n- Fine! Thank you.\n- You 're welcome."; | ||
| - | | ||
| - | // Βρες τα σημεία στίξης στην αρχή και το τέλος του δοθέντως αλφαριθμητικού | ||
| - | Pattern p = Pattern.compile(" | ||
| - | Matcher m = p.matcher(input); | ||
| - | while(m.find()) { | ||
| - | System.out.println(" | ||
| - | } | ||
| - | } | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | |||
| - | ===== Μετρητές επαναλήψεων ===== | ||
| - | |||
| - | Σε ένα πρότυπο συχνά θέλουμε να εκφράσουμε ότι ένα συγκεκριμένο πρότυπο ή τμήμα του συνολικού προτύπου εμφανίζεται μία ή περισσότερες φορές. Για παράδειγμα, | ||
| - | |||
| - | <code java Regexp.java> | ||
| - | import java.util.regex.*; | ||
| - | |||
| - | public class Regexp { | ||
| - | public static void main(String []args) { | ||
| - | String input = " | ||
| - | | ||
| - | // Βρες αλφαριθμητικά που αρχίζουν από g ή d ακολουθούν δύο χαρακτήρες o και τελειώνουν σε g ή d. | ||
| - | Pattern p = Pattern.compile(" | ||
| - | Matcher m = p.matcher(input); | ||
| - | while(m.find()) { | ||
| - | System.out.println(" | ||
| - | } | ||
| - | } | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | === Greedy quantifiers === | ||
| - | |||
| - | < | ||
| - | X? X, once or not at all | ||
| - | X* X, zero or more times | ||
| - | X+ X, one or more times | ||
| - | X{n} X, exactly n times | ||
| - | X{n,} X, at least n times | ||
| - | X{n,m} X, at least n but not more than m times | ||
| - | </ | ||
| - | |||
| - | === Reluctant quantifiers === | ||
| - | |||
| - | < | ||
| - | X?? X, once or not at all | ||
| - | X*? X, zero or more times | ||
| - | X+? X, one or more times | ||
| - | X{n}? X, exactly n times | ||
| - | X{n,}? X, at least n times | ||
| - | X{n,m}? X, at least n but not more than m times | ||
| - | </ | ||
| - | |||
| - | === Διάκριση μεταξύ greedy quantifiers και reluctant quantifiers === | ||
| - | |||
| - | Όταν χρησιμοποιούνται **greedy quantifiers** η μηχανή εντοπισμού των //regular expressions// | ||
| - | |||
| - | Για να διαπιστώσετε την αλλαγή στη συμπεριφορά της μηχανής εντοπισμού των regular-expressions, | ||
| - | |||
| - | <code java Regexp.java> | ||
| - | import java.util.regex.*; | ||
| - | |||
| - | public class Regexp { | ||
| - | public static void main(String []args) { | ||
| - | String input = "< | ||
| - | | ||
| - | // Βρες αλφαριθμητικά που αρχίζουν από τον χαρακτήρα '<' | ||
| - | Pattern p = Pattern.compile("< | ||
| - | //Pattern p = Pattern.compile("< | ||
| - | | ||
| - | Matcher m = p.matcher(input); | ||
| - | while(m.find()) { | ||
| - | System.out.println(" | ||
| - | } | ||
| - | } | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | |||
| - | |||
| - | ===== Ειδικοί χαρακτήρες ===== | ||
| - | |||
| - | Τα regular-expressions εισάγουν ειδικούς χαρακτήρες, | ||
| - | * the backslash **\**, | ||
| - | * the caret **^**, | ||
| - | * the dollar sign **$**, | ||
| - | * the period or dot **.**, | ||
| - | * the vertical bar or pipe symbol **|**, | ||
| - | * the question mark **? | ||
| - | * the asterisk or star *****, | ||
| - | * the plus sign **+**, | ||
| - | * the opening parenthesis **(**, | ||
| - | * the closing parenthesis **)**, | ||
| - | * the opening square bracket **[**, | ||
| - | * and the opening curly brace **{** | ||
| - | |||
| - | Όταν οι παραπάνω χαρακτήρες αναζητούνται (ως απλοί χαρακτήρες) μέσα σε ένα πρότυπο (// | ||
| - | |||
| - | <code java Regexp.java> | ||
| - | import java.util.regex.*; | ||
| - | |||
| - | public class Regexp { | ||
| - | public static void main(String []args) { | ||
| - | String input = "Can you locate all ? (question marks), dollar signs($), carrets(^) | ||
| - | | ||
| - | // Βρες αλφαριθμητικά που αρχίζουν από τον χαρακτήρα '<' | ||
| - | Pattern p = Pattern.compile(" | ||
| - | //Pattern p = Pattern.compile(" | ||
| - | Matcher m = p.matcher(input); | ||
| - | while(m.find()) { | ||
| - | System.out.println(" | ||
| - | } | ||
| - | } | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | <WRAP tip 80% center round> | ||
| - | Εναλλακτικά το δοθέν pattern θα μπορούσε να γραφεί όπως στη γραμμή σε σχόλια. Μέσα σε αγκύλες '' | ||
| - | |||
| - | Η παρακάτω δήλωση είναι λάθος, καθώς ο χαρακτήρας '' | ||
| - | <code java> | ||
| - | Pattern p = Pattern.compile(" | ||
| - | </ | ||
| - | </ | ||
| - | |||
| - | |||
| - | |||
| - | ===== Grouping ===== | ||
| - | |||
| - | Η μηχανή των regular-expressions δίνει τη δυνατότητα να εντοπίζονται υπό-πρότυπα (sub-patterns)μέσα στο συνολικό regular-expressions, | ||
| - | |||
| - | Η αρίθμηση των groups γίνεται μετρώντας τις παρενθέσεις που ανοίγουν από τα αριστερά προς τα δεξιά. Το group(0) είναι πάντοτε το συνολικό (γενικό) regular expression match. Για παράδειγμα στην έκφραση | ||
| - | |||
| - | < | ||
| - | 0 | ||
| - | 1 (A) | ||
| - | 2 | ||
| - | 3 (C) | ||
| - | </ | ||
| - | |||
| - | Δείτε το παρακάτω παράδειγμα, | ||
| - | |||
| - | <code java> | ||
| - | import java.util.regex.*; | ||
| - | |||
| - | public class Regexp { | ||
| - | public static void main(String []args) { | ||
| - | String str = " | ||
| - | Pattern p = Pattern.compile(" | ||
| - | Matcher m = p.matcher(str); | ||
| - | while(m.find()) { | ||
| - | System.out.println(" | ||
| - | System.out.println(" | ||
| - | System.out.println(" | ||
| - | } | ||
| - | } | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | Το παρακάτω παράδειγμα εκτυπώνει τα εξής; | ||
| - | <code > | ||
| - | group(0): Learning irregular | ||
| - | group(1): Learning irregular | ||
| - | group(2): Learning | ||
| - | group(3): irregular | ||
| - | group(0): learning regular | ||
| - | group(1): learning regular | ||
| - | group(2): learning | ||
| - | group(3): regular | ||
| - | </ | ||
| - | |||