Ein Freund fragte mich dies und ich war verblüfft: Gibt es eine Möglichkeit, einen regulären Ausdruck zu erzeugen, der einer Sequenz des gleichen Charakters entspricht? ZB Übereinstimmung auf 'aaa', 'bbb', aber nicht 'abc'?
m|\w{2,3}|
Ich würde den Trick nicht machen, da er mit 'abc' übereinstimmen würde.
m|a{2,3}|
Ich würde den Trick nicht machen, da er nicht mit 'bbb', 'ccc' usw. übereinstimmen würde.
Sichere Sache! Gruppierung und Referenzen sind deine Freunde:
(.)\1+
Entspricht 2 oder mehr Vorkommen des gleichen Charakters. Verwenden Sie nur für Word-Bestandteile \w
anstelle von .
, d. H .:
(\w)\1+
Beachten Sie, dass wir in Perl 5.10 auch alternative Notationen für Rückreferenzen haben.
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 /(?<char>\w)\k<char>+/;
}
Dies entspricht mehr als\w wie @@@:
/(.)\1+/
Dies ist auch mit reinen regulären Ausdrücken möglich (d. H. Mit regulären Sprachen - nicht Perl-Regexx). Leider bedeutet dies einen Regex, dessen Länge der Größe des Alphabets proportional ist, z.
(a* + b* + ... + z*)
Wo a ... z sind die Symbole im endlichen Alphabet.
Perl regexps, obwohl eine Obermenge reiner regulärer Ausdrücke, hat definitiv ihre Vorteile, selbst wenn Sie sie nur für reine reguläre Ausdrücke verwenden möchten!
Dafür gibt es Rückreferenzen.
m/(\w)\1\1/
wird den Trick tun.
Wenn Sie Java verwenden und doppelte Zeichen in der angegebenen Zeichenfolge finden, ist der Code hier
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!");
}
}
}
Meine eigene Frage beantworten, aber verstanden:
m|(\w)\1+|