Κοινή χρήση τεχνολογίας

σε κανονικές εκφράσεις

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Σε κανονικές εκφράσεις,; Μπορεί να αντιπροσωπεύει ποσότητα, 0 ή 1 φορές, που ισοδυναμεί με {0, 1} ή μπορεί να χρησιμοποιηθεί ως ειδικός χαρακτήρας για να αναπαραστήσει άλλες έννοιες.

μη λαίμαργο ταίριασμα

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

Ας δούμε ένα παράδειγμα:

  1. @Test
  2. public void test() {
  3. Pattern pattern = Pattern.compile("a.*?");
  4. Matcher matcher = pattern.matcher("abcabc");
  5. if (matcher.matches()) {
  6. System.out.println(matcher.group());
  7. }
  8. }

Έξοδος μετά την εκτέλεση: abcabc

Δεν είναι το πιο σύντομο ταίρι; Γιατί απέτυχε;

Αυτό στην πραγματικότητα περιλαμβάνει τους κανόνες της μη άπληστης αντιστοίχισης:Για μη άπληστη αντιστοίχιση, η συντομότερη διαδρομή αντιστοιχίζεται πριν από τον επόμενο κανόνα.

Δηλαδή, αν εμφανιστεί μόνο το "a.*?"

Ας δούμε τη σωστή χρήση:

  1. @Test
  2. public void test() {
  3. Pattern pattern = Pattern.compile("(a.*?)(.*)");
  4. Matcher matcher = pattern.matcher("afcafc");
  5. if (matcher.matches()) {
  6. System.out.println(matcher.group(0));
  7. System.out.println(matcher.group(1));
  8. System.out.println(matcher.group(2));
  9. }
  10. }

Έξοδος μετά την εκτέλεση:

  1. afcafc
  2. a
  3. fcafc

Όπως μπορείτε να δείτε, η πρώτη ομάδα λήψης συλλαμβάνει τη συντομότερη συμβολοσειρά "a" και η δεύτερη ομάδα λήψης καταγράφει "fcafc".

Ας ρίξουμε μια ματιά στις άλλες δύο καταστάσεις:

  • "(a.*)(.*)" Η πρώτη ομάδα λήψης θα καταγράψει τα πάντα, η δεύτερη ομάδα λήψης δεν θα αναφέρει σφάλμα, αλλά δεν θα καταγράψει τίποτα.
  • "(a.*?)(.*?)" Η πρώτη ομάδα σύλληψης θα συλλάβει το "a" και η δεύτερη ομάδα θα συλλάβει το "fcafc" Δεδομένου ότι δεν υπάρχουν άλλοι κανόνες αργότερα, θα υποβληθεί σε επεξεργασία σύμφωνα με άπληστη αντιστοίχιση .

Ταίριασμα αλλά δεν γίνεται λήψη (?:pattern)

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

Ας δούμε ένα παράδειγμα

  1. @Test
  2. public void test0() {
  3. Pattern pattern = Pattern.compile("\d{4}-(?:[a-z]+)");
  4. Matcher matcher = pattern.matcher("3214-opo");
  5. if (matcher.matches()) {
  6. System.out.println(matcher.group());
  7. System.out.println(matcher.group(1)); // 报错
  8. }
  9. }

Θα αναφερθεί ένα σφάλμα κατά τη λήψη μέσω της ομάδας(1), δηλαδή, μπορεί να αντιστοιχιστεί αλλά δεν μπορεί να καταγραφεί. Εάν το ?: αφαιρεθεί, μπορεί να αποτυπωθεί κανονικά μέσω της ομάδας(1).

Ενεργοποίηση λειτουργίας μίας γραμμής (?s)

Το (?s) ενεργοποιεί τη λειτουργία μονής γραμμής στη δεξιά πλευρά, κάνοντας το να ταιριάζει με οποιονδήποτε χαρακτήρα, συμπεριλαμβανομένου του χαρακτήρα n νέας γραμμής.

Ας δούμε ένα παράδειγμα:

  1. private static final String DEFAULT_VARIABLE_PATTERN = "((?s).*)";
  2. /**
  3. * 从输出结果可知,匹配到了换行符 'n'
  4. */
  5. @Test
  6. public void test4() {
  7. Pattern pattern = Pattern.compile(DEFAULT_VARIABLE_PATTERN);
  8. Matcher matcher = pattern.matcher("abcnsdf");
  9. if (matcher.matches()) {
  10. System.out.println(matcher.group());
  11. System.out.println(matcher.group(1));
  12. System.out.println(matcher.group(2)); // (?s) 不能作为捕获组,报错
  13. }
  14. }

Κατά τη λήψη, το (?s) δεν μπορεί να καταγραφεί ως ομάδα λήψης, επομένως το "((?s).*)" μπορεί να καταγράψει την ομάδα(1) το πολύ, και θα αναφερθεί ένα σφάλμα κατά τη λήψη της ομάδας(2).

  1. @Test
  2. public void test5() {
  3. Pattern pattern = Pattern.compile("(.*)");
  4. Matcher matcher = pattern.matcher("abcnsdf");
  5. if (matcher.matches()) {
  6. System.out.println(matcher.group());
  7. System.out.println(matcher.group(1));
  8. }
  9. }

Αφού αφαιρέσετε το (?s), προσπαθήστε να ταιριάξετε το "abcnsdf" Επειδή υπάρχει ένας χαρακτήρας νέας γραμμής, η αντιστοίχιση δεν μπορεί να ολοκληρωθεί, επομένως δεν θα βγει τίποτα.