Wyrażenie regularne do dopasowania dowolnego znaku powtarzanego więcej niż 10 razy


107

Szukam prostego wyrażenia regularnego, które pasowałoby do tego samego znaku powtarzanego więcej niż 10 razy. Na przykład, jeśli mam dokument zaśmiecony poziomymi liniami:

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

Dopasuje linię =znaków, ponieważ jest powtarzana więcej niż 10 razy. Zauważ , że chciałbym, żeby to działało dla każdej postaci.


2
tytuł tej odpowiedzi jest mylący, powinieneś powiedzieć: „Wyrażenie regularne w celu dopasowania dowolnego znaku powtórzonego więcej niż 10 razy”
dalloliogm

Odpowiedzi:


157

Wymagane wyrażenie regularne to /(.)\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;

Tutaj \1nazywa się odwołaniem wstecznym. Odnosi się do tego, co jest oznaczone kropką .między nawiasami, (.)a następnie {9,}prosi o dziewięć lub więcej tego samego znaku. W ten sposób pasuje do dziesięciu lub więcej dowolnych znaków.

Chociaż powyższy skrypt testowy jest w Perlu, jest to bardzo standardowa składnia wyrażeń regularnych i powinna działać w każdym języku. W niektórych wariantach możesz potrzebować więcej odwrotnych ukośników, np. Emacs zmusi cię do napisania \(.\)\1\{9,\}tutaj.

Jeśli cały ciąg powinien składać się z 9 lub więcej identycznych znaków, dodaj kotwice wokół wzoru:

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

28

W Pythonie możesz użyć (.)\1{9,}

  • (.) tworzy grupę z jednego znaku (dowolnego znaku)
  • \ 1 {9,} oznacza dziewięć lub więcej znaków z 1. grupy

przykład:

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

Wynik:

1. aaaaaaaaaaaaaaa
3. cccccccccccccccccccc
5. eeeeeeeeeeee

if re.search (line): print line (przypisanie zmiennej rxx nie jest konieczne)
dalloliogm

1
Masz rację w tym prostym kontekście. Używając zmiennej rxx mogę zrobić coś takiego jak rxx.group (1), rxx.start (1) itd.
Michał Niklas

5

.pasuje do dowolnego znaku. Używany w połączeniu ze wspomnianymi już aparatami ortodontycznymi:

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


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

Cześć Jeek i @SilentGhost. Te dwa polecenia grep -E '([=o])\1{10}' testi grep -E '([=o]){10}' testdziałają dobrze z twoim przykładem (zwróć uwagę na brak \1w drugim poleceniu). Ale polecenie grep -E '([=o])\1{10}' <<< '==o==o==o==o==o==o===o==o==='nie pasuje do linii! Jednak komenda bez \1meczów linia: grep -E '([=o]){10}' <<< '==o==o==o==o==o==o===o==o==='. Czy mógłbyś to wyjaśnić? Pozdrawiam;)
olibre


1

użyj operatora {10,}:

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

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

1

Możesz także użyć programu PowerShell, aby szybko zamienić słowa lub powtórzenia znaków. PowerShell jest przeznaczony dla systemu Windows. Obecna wersja to 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_replacePrzykład PHP :

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

Tutaj [a-z]uderza w znak, ()a następnie pozwala na użycie go z \\1odwołaniem wstecznym, który próbuje dopasować inny ten sam znak (zauważ, że jest to już skierowane na 2 kolejne znaki), a zatem:

matka ojciec

Jeśli tak:

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

oznaczałoby to wymazanie 3 kolejnych powtarzających się znaków, wypisując:

moherbb ją


0
={10,}

dopasowania, =które powtarza się 10 lub więcej razy.


1
jesteś pewien, że to nie zajmuje 10 lub więcej dowolnych znaków?
Etan

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

było źle, ale zostało zredagowane (aby dopasować moją odpowiedź, która otrzymała kilka głosów negatywnych, dobrze)
dalloliogm

2
Ojej, nie wiedziałem, że muszę wyraźnie powiedzieć, że możesz zastąpić postać czymkolwiek zechcesz.
SilentGhost

0

Nieco bardziej ogólny przykład PowerShell. W PowerShell 7 dopasowanie jest podświetlane, łącznie z ostatnią spacją (czy możesz wyróżnić na stosie?).

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

a b c d e f 
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.