Biểu thức chính quy để khớp với bất kỳ ký tự nào được lặp lại hơn 10 lần


106

Tôi đang tìm một biểu thức chính quy đơn giản để khớp với cùng một ký tự được lặp lại hơn 10 lần. Vì vậy, ví dụ: nếu tôi có một tài liệu rải rác với các đường ngang:

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

Nó sẽ khớp với dòng =ký tự vì nó được lặp lại hơn 10 lần. Lưu ý rằng tôi muốn điều này làm việc cho bất kỳ nhân vật nào .


2
tiêu đề của asnwer này gây hiểu lầm, bạn nên nói 'Biểu thức chính quy để khớp với bất kỳ ký tự nào được lặp lại nhiều hơn 10 lần'
dalloliogm

Câu trả lời:


157

Regex bạn cần là /(.)\1{9,}/.

Kiểm tra:

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

Đây \1được gọi là một backreference. Nó tham chiếu những gì được ghi lại bởi dấu chấm .giữa dấu ngoặc (.)và sau đó là {9,}yêu cầu cho chín hoặc nhiều ký tự giống nhau. Vì vậy, điều này khớp với mười hoặc nhiều hơn bất kỳ ký tự đơn nào.

Mặc dù kịch bản kiểm tra ở trên bằng Perl, đây là cú pháp regex rất chuẩn và sẽ hoạt động ở bất kỳ ngôn ngữ nào. Trong một số biến thể, bạn có thể cần sử dụng nhiều dấu gạch chéo ngược hơn, ví dụ như Emacs sẽ khiến bạn viết \(.\)\1\{9,\}ở đây.

Nếu toàn bộ chuỗi phải bao gồm 9 ký tự giống nhau trở lên, hãy thêm các ký tự neo xung quanh mẫu:

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

28

Trong Python, bạn có thể sử dụng (.)\1{9,}

  • (.) tạo nhóm từ một ký tự (ký tự bất kỳ)
  • \ 1 {9,} khớp với chín ký tự trở lên từ nhóm thứ nhất

thí dụ:

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

Đầu ra:

1. aaaaaaaaaaaaaaa
3. cccccccccccccccccccc
5. eeeeeeeeeeee

nếu re.search (dòng): dòng in (các assignemnt vào biến rxx là không cần thiết)
dalloliogm

1
Bạn đã đúng trong bối cảnh đơn giản này. Sử dụng biến rxx, tôi có thể thực hiện một số việc như rxx.group (1), rxx.start (1), v.v.
Michał Niklas

5

.khớp với bất kỳ ký tự nào. Được sử dụng cùng với dấu ngoặc nhọn đã được đề cập:

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


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

Xin chào Jeek và @SilentGhost. Hai lệnh grep -E '([=o])\1{10}' testgrep -E '([=o]){10}' testhoạt động tốt với ví dụ của bạn (lưu ý thiếu \1lệnh thứ hai). Nhưng lệnh grep -E '([=o])\1{10}' <<< '==o==o==o==o==o==o===o==o==='không khớp với dòng! Tuy nhiên lệnh mà không cần \1diêm dòng: grep -E '([=o]){10}' <<< '==o==o==o==o==o==o===o==o==='. Xin vui lòng bạn có thể giải thích? Chúc mừng;)
olibre

3

Trên một số ứng dụng, bạn cần xóa dấu gạch chéo để làm cho nó hoạt động.

/(.)\1{9,}/

hoặc cái này:

(.)\1{9,}

1

sử dụng toán tử {10,}:

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

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

1

Bạn cũng có thể sử dụng PowerShell để nhanh chóng thay thế các từ hoặc biểu tượng ký tự. PowerShell dành cho Windows. Phiên bản hiện tại là 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_replaceVí dụ của PHP :

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

Tại đây [a-z]nhấn vào ký tự, ()sau đó cho phép nó được sử dụng với \\1backreference để tìm cách khớp với một ký tự khác tương tự (lưu ý rằng điều này đang nhắm mục tiêu đến 2 ký tự liên tiếp), do đó:

bố mẹ

Nếu bạn đã làm:

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

nghĩa là sẽ xóa 3 ký tự lặp lại liên tiếp, xuất ra:

moherbb cô ấy


0
={10,}

các trận đấu =được lặp lại từ 10 lần trở lên.


1
chắc chắn rằng điều này không có 10 ký tự tùy ý trở lên?
Etan

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

đó là sai, nhưng nó đã được chỉnh sửa (để phù hợp với câu trả lời của tôi mà có một số downvotes, tốt)
dalloliogm

2
Gee, tôi không biết tôi phải nói rõ ràng rằng bạn có thể thay thế nhân vật bằng bất cứ thứ gì bạn muốn.
SilentGhost

0

Một ví dụ về powershell chung chung hơn một chút. Trong powershell 7, trận đấu được đánh dấu bao gồm khoảng trống cuối cùng (bạn có thể đánh dấu trong ngăn xếp không?).

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

a b c d e f 
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.