Un amico mi ha chiesto questo e sono rimasto perplesso: esiste un modo per creare un’espressione regolare che corrisponda a una sequenza dello stesso personaggio? Ad esempio, corrisponde a “aaa”, “bbb”, ma non “abc”?
m|\w{2,3}|
Non farebbe il trucco in quanto corrisponderebbe a ‘abc’.
m|a{2,3}|
Non farebbe il trucco in quanto non corrisponderebbe a ‘bbb’, ‘ccc’, ecc.
Cosa certa! Raggruppamento e riferimenti sono i tuoi amici:
(.)\1+
Corrisponde a 2 o più occorrenze dello stesso personaggio. Solo per i caratteri costituenti della parola, utilizzare \w
anziché .
, cioè:
(\w)\1+
Notare che in Perl 5.10 abbiamo anche delle notazioni alternative per i backreferences.
foreach (qw(aaa bbb abc)) { say; say ' original' if /(\w)\1+/; say ' new way' if /(\w)\g{1}+/; say ' relative' if /(\w)\g{-1}+/; say ' named' if /(?'char'\w)\g{char}+/; say ' named' if /(?\w)\k +/; }
Questo corrisponderà a più di \ w , come @@@:
/(.)\1+/
Ecco a cosa servono le backreferences.
m/(\w)\1\1/
farà il trucco.
Ciò è anche ansible usando espressioni regolari pure (cioè quelle che descrivono le lingue regolari – non le espressioni regolari di Perl). Sfortunatamente, significa un’espressione regolare la cui lunghezza è proporzionale alla dimensione dell’alfabeto, ad esempio:
(a* + b* + ... + z*)
Dove a … z sono i simboli dell’alfabeto finito.
Quindi Perl regexps, sebbene sia un superset di pure espressioni regolari, ha sicuramente i suoi vantaggi anche quando vuoi semplicemente usarli per pura espressione regolare!
Rispondere alla mia domanda, ma l’ho capito:
m|(\w)\1+|
Se stai usando Java e trovi caratteri duplicati in una determinata stringa, ecco il codice,
public class Test { public static void main(String args[]) { String s = "abbc"; if (s.matches(".*([a-zA-Z])\\1+.*")) { System.out.println("Duplicate found!"); } else { System.out.println("Duplicate not found!"); } }
}