Expressão regular para corresponder a qualquer caractere sendo repetido mais de 10 vezes


107

Estou procurando uma expressão regular simples para corresponder ao mesmo caractere que está sendo repetido mais de 10 ou mais vezes. Por exemplo, se eu tiver um documento cheio de linhas horizontais:

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

Ele corresponderá à linha de =caracteres porque é repetido mais de 10 vezes. Observe que eu gostaria que isso funcionasse para qualquer personagem.


2
o título desta resposta é enganoso, você deveria ter dito 'Expressão regular para corresponder a qualquer caractere repetido mais de 10 vezes'
dalloliogm

Respostas:


157

O regex de que você precisa é /(.)\1{9,}/.

Teste:

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

Aqui, o \1é chamado de referência anterior. Ele faz referência ao que é capturado pelo ponto .entre os colchetes (.)e, em seguida, {9,}pede nove ou mais do mesmo caractere. Portanto, isso corresponde a dez ou mais de qualquer caractere único.

Embora o script de teste acima esteja em Perl, esta é uma sintaxe regex muito padrão e deve funcionar em qualquer idioma. Em algumas variantes, você pode precisar usar mais barras invertidas, por exemplo, o Emacs faria você escrever \(.\)\1\{9,\}aqui.

Se uma string inteira deve consistir em 9 ou mais caracteres idênticos, adicione âncoras ao redor do padrão:

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

28

Em Python você pode usar (.)\1{9,}

  • (.) faz grupo de um char (qualquer char)
  • \ 1 {9,} corresponde a nove ou mais caracteres do primeiro grupo

exemplo:

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

Resultado:

1. aaaaaaaaaaaaaaa
3. cccccccccccccccccccc
5. eeeeeeeeeeee

if re.search (line): print line (a atribuição à variável rxx não é necessária)
dalloliogm

1
Você está certo neste contexto simples. Usando a variável rxx, posso fazer algo como rxx.group (1), rxx.start (1) etc.
Michał Niklas

5

.corresponde a qualquer personagem. Usado em conjunto com as chaves já mencionadas:

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


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

Olá, Jeek e @SilentGhost. Os dois comandos grep -E '([=o])\1{10}' teste grep -E '([=o]){10}' testfunciona bem com o seu exemplo (note a falta de \1no segundo comando). Mas o comando grep -E '([=o])\1{10}' <<< '==o==o==o==o==o==o===o==o==='não corresponde à linha! No entanto, o comando sem \1partidas a linha: grep -E '([=o]){10}' <<< '==o==o==o==o==o==o===o==o==='. Por favor, você poderia explicar? Saúde;)
olibre

3

Em alguns aplicativos, você precisa remover as barras para que funcione.

/(.)\1{9,}/

ou isto:

(.)\1{9,}

1

use o operador {10,}:

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

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

1

Você também pode usar o PowerShell para substituir palavras ou reptições de caracteres rapidamente. PowerShell é para Windows. A versão atual é 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_replaceExemplo de PHP :

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

Aqui [a-z]atinge o caractere ()e permite que ele seja usado com referência anterior \\1que tenta corresponder a outro mesmo caractere (observe que isso já está direcionando 2 caracteres consecutivos), assim:

mãe pai

Se você fez:

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

isso estaria apagando 3 caracteres repetidos consecutivos, gerando:

moherbb ela


0
={10,}

corresponde a =que é repetido 10 ou mais vezes.


1
certeza de que isso não leva 10 ou mais caracteres arbitrários?
Etan

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

estava errado, mas foi editado (para corresponder à minha resposta que teve alguns
votos negativos

2
Puxa, não sabia que tinha que dizer explicitamente que você pode substituir o personagem com o que quiser.
SilentGhost

0

Um exemplo de PowerShell um pouco mais genérico. No PowerShell 7, a correspondência é destacada incluindo o último espaço (você pode destacar na pilha?).

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

a b c d e f 
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.