Regulärer Ausdruck für jedes Zeichen, das mehr als 10 Mal wiederholt wird

106

Ich suche nach einem einfachen regulären Ausdruck, der dem gleichen Zeichen entspricht, das mehr als 10 Mal wiederholt wird. Wenn ich zum Beispiel ein Dokument mit horizontalen Linien habe:

=================================================

Es stimmt mit der Zeichenzeile überein, =da es mehr als 10 Mal wiederholt wird. Beachten Sie, dass dies für jeden Charakter funktionieren soll .

Justin
quelle
2
Der Titel dieser Antwort ist irreführend. Sie sollten gesagt haben: "Regulärer Ausdruck für jedes Zeichen, das mehr als 10 Mal wiederholt wurde"
Dallas

Antworten:

157

Die Regex, die Sie brauchen, ist /(.)\1{9,}/.

Prüfung:

#!perl
use warnings;
use strict;
my $regex = qr/(.)\1{9,}/;
print "NO" if "abcdefghijklmno" =~ $regex;
print "YES" if "------------------------" =~ $regex;
print "YES" if "========================" =~ $regex;

Hier \1wird das eine Rückreferenz genannt. Es verweist darauf, was durch den Punkt .zwischen den Klammern erfasst wird, (.)und {9,}fragt dann nach neun oder mehr gleichen Zeichens. Dies entspricht also zehn oder mehr einzelnen Zeichen.

Obwohl sich das obige Testskript in Perl befindet, ist dies eine Standard-Regex-Syntax und sollte in jeder Sprache funktionieren. In einigen Varianten müssen Sie möglicherweise mehr Backslashes verwenden, z. B. würde Emacs Sie dazu bringen, \(.\)\1\{9,\}hier zu schreiben .

Wenn eine ganze Zeichenfolge aus 9 oder mehr identischen Zeichen bestehen soll, fügen Sie Anker um das Muster hinzu:

my $regex = qr/^(.)\1{9,}$/;
Wiktor Stribiżew
quelle
28

In Python können Sie verwenden (.)\1{9,}

  • (.) macht eine Gruppe aus einem Zeichen (ein beliebiges Zeichen)
  • \ 1 {9,} entspricht neun oder mehr Zeichen aus der 1. Gruppe

Beispiel:

txt = """1. aaaaaaaaaaaaaaa
2. bb
3. cccccccccccccccccccc
4. dd
5. eeeeeeeeeeee"""
rx = re.compile(r'(.)\1{9,}')
lines = txt.split('\n')
for line in lines:
    rxx = rx.search(line)
    if rxx:
        print line

Ausgabe:

1. aaaaaaaaaaaaaaa
3. cccccccccccccccccccc
5. eeeeeeeeeeee
Michał Niklas
quelle
if re.search (Zeile): Zeile drucken (die Zuordnung zur rxx-Variablen ist nicht erforderlich)
dalloliogm
1
Sie haben Recht in diesem einfachen Kontext. Mit der Variablen rxx kann ich so etwas wie rxx.group (1), rxx.start (1) usw. machen
Michał Niklas
5

.passt zu einem beliebigen Zeichen. Wird in Verbindung mit den bereits erwähnten geschweiften Klammern verwendet:

$: cat > test
========
============================
oo
ooooooooooooooooooooooo


$: grep -E '(.)\1{10}' test
============================
ooooooooooooooooooooooo
jeekl
quelle
Hallo Jeek und @SilentGhost. Die beiden Befehle grep -E '([=o])\1{10}' testund grep -E '([=o]){10}' testfunktioniert gut mit Ihrem Beispiel ( man beachte das Fehlen \1im zweiten Befehl). Aber der Befehl grep -E '([=o])\1{10}' <<< '==o==o==o==o==o==o===o==o==='stimmt nicht mit der Zeile überein! Der Befehl ohne \1stimmt jedoch mit der Zeile überein : grep -E '([=o]){10}' <<< '==o==o==o==o==o==o===o==o==='. Könnten Sie bitte erklären? Prost;)
Olibre
3

Bei einigen Apps müssen Sie die Schrägstriche entfernen, damit es funktioniert.

/(.)\1{9,}/

oder dieses:

(.)\1{9,}
Patoshi パ ト シ
quelle
1

Verwenden Sie den Operator {10,}:

$: cat > testre
============================
==
==============

$: grep -E '={10,}' testre
============================
==============
dalloliogm
quelle
1

Sie können PowerShell auch verwenden , um Wörter oder Zeichenreptionen schnell zu ersetzen . PowerShell ist für Windows. Aktuelle Version ist 3.0.

$oldfile = "$env:windir\WindowsUpdate.log"

$newfile = "$env:temp\newfile.txt"
$text = (Get-Content -Path $oldfile -ReadCount 0) -join "`n"

$text -replace '/(.)\1{9,}/', ' ' | Set-Content -Path $newfile
BÖSE
quelle
1

PHP- preg_replaceBeispiel:

$str = "motttherbb fffaaattther";
$str = preg_replace("/([a-z])\\1/", "", $str);
echo $str;

Hier [a-z]trifft das Zeichen und ()ermöglicht dann die Verwendung mit \\1Rückreferenz, die versucht, mit einem anderen gleichen Zeichen übereinzustimmen (dies zielt bereits auf 2 aufeinanderfolgende Zeichen ab), also:

Mutter Vater

Wenn du. .. getan hast:

$str = preg_replace("/([a-z])\\1{2}/", "", $str);

das würde 3 aufeinanderfolgende wiederholte Zeichen löschen und Folgendes ausgeben:

moherbb sie

LihO
quelle
0
={10,}

Übereinstimmungen =, die 10 oder mehr Mal wiederholt werden.

SilentGhost
quelle
1
sicher, dass dies nicht 10 oder mehr beliebige Zeichen akzeptiert?
Etan
perl -e 'print "NO" if "abcdefghijklmno" =~ /.{10,}/;'
es war falsch, aber es wurde bearbeitet (passend zu meiner Antwort, die einige negative Stimmen bekam, gut)
dalloliogm
2
Ich wusste nicht, dass ich explizit sagen muss, dass du den Charakter durch alles ersetzen kannst, was du willst.
SilentGhost
0

Ein etwas allgemeineres Powershell-Beispiel. In Powershell 7 wird die Übereinstimmung einschließlich des letzten Leerzeichens hervorgehoben (können Sie sie im Stapel hervorheben?).

'a b c d e f ' | select-string '([a-f] ){6,}'

a b c d e f 
js2010
quelle