Espressione regolare per trovare qualsiasi carattere ripetuto più di 10 volte


107

Sto cercando una semplice espressione regolare per abbinare lo stesso carattere ripetuto più di 10 volte. Quindi, ad esempio, se ho un documento disseminato di linee orizzontali:

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

Corrisponderà alla riga di =caratteri perché viene ripetuta più di 10 volte. Nota che mi piacerebbe che questo funzionasse per qualsiasi personaggio.


2
il titolo di questa risposta è fuorviante, avresti dovuto dire "Espressione regolare per abbinare qualsiasi carattere ripetuto più di 10 volte"
dalloliogm

Risposte:


157

La regex di cui hai bisogno è /(.)\1{9,}/.

Test:

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

Qui \1viene chiamato backreference. Fa riferimento a ciò che viene catturato dal punto .tra le parentesi (.)e quindi {9,}richiede nove o più dello stesso carattere. Quindi questo corrisponde a dieci o più di ogni singolo carattere.

Sebbene lo script di test sopra sia in Perl, questa è una sintassi regex molto standard e dovrebbe funzionare in qualsiasi lingua. In alcune varianti potresti aver bisogno di usare più backslash, ad esempio Emacs ti farebbe scrivere \(.\)\1\{9,\}qui.

Se un'intera stringa deve essere composta da 9 o più caratteri identici, aggiungi degli ancoraggi attorno al modello:

my $regex = qr/^(.)\1{9,}$/;

28

In Python puoi usare (.)\1{9,}

  • (.) crea un gruppo da un carattere (qualsiasi carattere)
  • \ 1 {9,} corrisponde a nove o più caratteri del primo gruppo

esempio:

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

Produzione:

1. aaaaaaaaaaaaaaa
3. cccccccccccccccccccc
5. eeeeeeeeeeee

if re.search (line): print line (l'assegnazione alla variabile rxx non è necessaria)
dalloliogm

1
Hai ragione in questo semplice contesto. Usando la variabile rxx posso fare qualcosa come rxx.group (1), rxx.start (1) ecc.
Michał Niklas

5

.corrisponde a qualsiasi carattere. Utilizzato in combinazione con le parentesi graffe già menzionate:

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


$: grep -E '(.)\1{10}' test
============================
ooooooooooooooooooooooo

Ciao Jeek e @SilentGhost. I due comandi grep -E '([=o])\1{10}' teste grep -E '([=o]){10}' testfunzionano bene con il tuo esempio (nota la mancanza di \1nel secondo comando). Ma il comando grep -E '([=o])\1{10}' <<< '==o==o==o==o==o==o===o==o==='non corrisponde alla riga! Tuttavia il comando senza \1partite la linea: grep -E '([=o]){10}' <<< '==o==o==o==o==o==o===o==o==='. Per favore potresti spiegare? Saluti;)
olibre

3

Su alcune app è necessario rimuovere le barre per farlo funzionare.

/(.)\1{9,}/

o questo:

(.)\1{9,}

1

usa l'operatore {10,}:

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

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

1

Puoi anche utilizzare PowerShell per sostituire rapidamente parole o ripetizioni di caratteri. PowerShell è per Windows. La versione attuale è 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

1

preg_replaceEsempio di PHP :

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

Qui [a-z]colpisce il carattere, ()quindi consente di utilizzarlo con il \\1backreference che cerca di abbinare un altro stesso carattere (nota che questo è già indirizzato a 2 caratteri consecutivi), quindi:

madre padre

Se avete fatto:

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

ciò significherebbe cancellare 3 caratteri ripetuti consecutivi, emettendo:

moherbb lei


0
={10,}

corrispondenze =ripetute 10 o più volte.


1
sicuro che questo non richieda 10 o più caratteri arbitrari?
Etan

perl -e 'print "NO" if "abcdefghijklmno" =~ /.{10,}/;'

era sbagliato, ma è stato modificato (per corrispondere alla mia risposta che ha ottenuto alcuni
voti negativi

2
Accidenti, non sapevo di dover dire esplicitamente che puoi sostituire il personaggio con qualsiasi cosa tu voglia.
SilentGhost

0

Un esempio di PowerShell leggermente più generico. In PowerShell 7, la corrispondenza viene evidenziata includendo l'ultimo spazio (puoi evidenziare nello stack?).

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

a b c d e f 
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.