Expression régulière pour correspondre à tout caractère répété plus de 10 fois


107

Je recherche une expression régulière simple pour correspondre au même caractère répété plus d'une dizaine de fois. Par exemple, si j'ai un document jonché de lignes horizontales:

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

Il correspondra à la ligne de =caractères car il est répété plus de 10 fois. Notez que j'aimerais que cela fonctionne pour n'importe quel personnage.


2
le titre de cette réponse est trompeur, vous auriez dû dire `` Expression régulière pour correspondre à n'importe quel caractère répété plus de 10 fois ''
dalloliogm

Réponses:


157

Le regex dont vous avez besoin est /(.)\1{9,}/.

Tester:

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

Ici, \1on appelle une référence arrière. Il fait référence à ce qui est capturé par le point .entre les crochets (.), puis {9,}demande neuf ou plus du même caractère. Ainsi, cela correspond à dix ou plus de n'importe quel caractère unique.

Bien que le script de test ci-dessus soit en Perl, il s'agit d'une syntaxe regex très standard et devrait fonctionner dans n'importe quel langage. Dans certaines variantes, vous devrez peut-être utiliser plus de barres obliques inverses, par exemple Emacs vous obligerait à écrire \(.\)\1\{9,\}ici.

Si une chaîne entière doit être composée de 9 caractères identiques ou plus, ajoutez des ancres autour du motif:

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

28

En Python, vous pouvez utiliser (.)\1{9,}

  • (.) fait un groupe à partir d'un caractère (n'importe quel caractère)
  • \ 1 {9,} correspond à neuf caractères ou plus du premier groupe

exemple:

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

Production:

1. aaaaaaaaaaaaaaa
3. cccccccccccccccccccc
5. eeeeeeeeeeee

if re.search (line): print line (l'affectation à la variable rxx n'est pas nécessaire)
dalloliogm

1
Vous avez raison dans ce contexte simple. En utilisant la variable rxx, je peux faire quelque chose comme rxx.group (1), rxx.start (1) etc.
Michał Niklas

5

.correspond à n'importe quel caractère. Utilisé en conjonction avec les accolades déjà mentionnées:

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


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

Salut Jeek et @SilentGhost. Les deux commandes grep -E '([=o])\1{10}' testet de grep -E '([=o]){10}' testbelles œuvres avec votre exemple (notez l'absence de \1la deuxième commande). Mais la commande grep -E '([=o])\1{10}' <<< '==o==o==o==o==o==o===o==o==='ne correspond pas à la ligne! Cependant , la commande sans \1correspondance dans la ligne: grep -E '([=o]){10}' <<< '==o==o==o==o==o==o===o==o==='. Pouvez-vous expliquer? Cheers;)
olibre

3

Sur certaines applications, vous devez supprimer les barres obliques pour que cela fonctionne.

/(.)\1{9,}/

ou ca:

(.)\1{9,}

1

utilisez l'opérateur {10,}:

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

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

1

Vous pouvez également utiliser PowerShell pour remplacer rapidement des mots ou des représentations de caractères. PowerShell est pour Windows. La version actuelle est la 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_replaceExemple de PHP :

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

Ici [a-z]frappe le personnage, ()puis lui permet d'être utilisé avec une \\1référence arrière qui tente de faire correspondre un autre même caractère (notez que cela cible déjà 2 caractères consécutifs), ainsi:

mère père

Si vous avez fait:

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

cela effacerait 3 caractères répétés consécutifs, produisant:

moherbb elle


0
={10,}

correspondances =répétées 10 fois ou plus.


1
sûr que cela ne prend pas 10 caractères arbitraires ou plus?
Etan

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

c'était faux, mais il a été modifié (pour correspondre à ma réponse qui a obtenu des
votes négatifs

2
Gee, je ne savais pas que je devais dire explicitement que vous pouvez remplacer le personnage par tout ce que vous voulez.
SilentGhost

0

Un exemple de PowerShell un peu plus générique. Dans PowerShell 7, le match est mis en évidence, y compris le dernier espace (pouvez-vous mettre en évidence dans la pile?).

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

a b c d e f 
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.