2012-06-14 41 views
5

Looking for a perl one-liner gì sẽ tìm thấy tất cả các từ với mô hình tiếp theo:lời Tìm kiếm với bất kỳ ký tự lặp lại

X(not_X_chrs)X(not_X_chrs)X e.g. cyclic 

Đối với một nhân vật, nó rất dễ dàng, ví dụ cho 'a'

perl -nle 'print if /^a[^a]+a[^a]+a$/' < /usr/share/dict/web2 

nhưng tôi muốn tìm kiếm BẤT CỨ nhân vật, vì vậy, tìm kiếm một regex cho việc tìm kiếm tất cả từ như:

azalea #repeating a 
baobab #repeating b 
cyclic #c 

và vân vân ..

đã thử điều này:

perl -nle 'print if m/^([a-z])[^$1]+$1[^$1]+$1$/i' </usr/share/dict/web2 

nhưng không hoạt động.

Trả lời

6
(?:(?!STRING).) 

(?:STRING) 

như

[^CHAR] 

CHAR 

vì vậy bạn có thể sử dụng

/ 
^
    (\pL) 
    (?: 
     (?:(?!\1).)+ 
     \1 
    ){2} 
    \z 
/sx 
3

Đây là regex tốt nhất mà tôi có thể đưa ra:

^([a-z])((?:(?!\1).)+\1){2}$ 

Thử nghiệm trên RegexPal.

0

Bạn cũng có thể sử dụng một lượng hóa lười biếng với một tổ chức phi quay lui nguyên tử:

^(\w)(?>\w*?\1){2}$ 

Altho mà chỉ hoạt động khi 0 ký tự trung gian là chấp nhận được.

Với ít nhất 1 ký tự bạn sẽ phải sử dụng một lookahead tiêu cực:

^(\w)(?>(?!\1)\w+?\1){2}$ 
0

Trong perlretut nó nói rằng bạn có thể backreference trong một regex (không phải là phần bên phải của quyền thay người) sử dụng \g1. Điều này đã được thay đổi trong 5,14. Vì tôi chỉ có 5.12.2 ở đây, tôi phải sử dụng \1 để thay thế.

Do đó, regex ban đầu của bạn với một adjustion nhỏ làm việc cho tôi:

use strict; use warnings; 
use 5.12.2; 
use feature qw(say); 
for (qw/ azalea baobab cyclic deadend teeeeeestest doesnotwork /) { 
    say if m/^([a-z])[^\1]+\1[^\1]+\1$/i; 
} 

Nhìn vào nó với YAPE::Regex::Explain

use YAPE::Regex::Explain; 
print YAPE::Regex::Explain->new(qr/^([a-z])[^\1]+\1[^\1]+\1$/i)->explain(); 

sản lượng:

The regular expression: 

(?i-msx:^([a-z])[^\1]+\1[^\1]+\1$) 

matches as follows: 


use YAPE::Regex::Explain; 
print YAPE::Regex::Explain->new(qr/^([a-z])[^\1]+\1[^\1]+\1$/i)->explain(); 

NODE      EXPLANATION 
---------------------------------------------------------------------- 
(?i-msx:     group, but do not capture (case-insensitive) 
         (with^and $ matching normally) (with . not 
         matching \n) (matching whitespace and # 
         normally): 
---------------------------------------------------------------------- 
^      the beginning of the string 
---------------------------------------------------------------------- 
    (      group and capture to \1: 
---------------------------------------------------------------------- 
    [a-z]     any character of: 'a' to 'z' 
---------------------------------------------------------------------- 
)      end of \1 
---------------------------------------------------------------------- 
    [^\1]+     any character except: '\1' (1 or more 
          times (matching the most amount possible)) 
---------------------------------------------------------------------- 
    \1      what was matched by capture \1 
---------------------------------------------------------------------- 
    [^\1]+     any character except: '\1' (1 or more 
          times (matching the most amount possible)) 
---------------------------------------------------------------------- 
    \1      what was matched by capture \1 
---------------------------------------------------------------------- 
    $      before an optional \n, and the end of the 
          string 
---------------------------------------------------------------------- 
)      end of grouping 
---------------------------------------------------------------------- 

Sửa: Địa chỉ một lớp lót là perl -e 'print if m/^([a-z])[^\1]+\1[^\1]+\1$/i'.

Ngày lưu ý khác, nếu bạn đã cố gắng perl -w -e 'print if m/(as)$1/' bạn muốn đã thấy vấn đề của bạn ngay lập tức:

$ perl -w -e 'print if m/(a)$1/' asdf 
Use of uninitialized value $1 in regexp compilation at -e line 1. 
Use of uninitialized value $_ in pattern match (m//) at -e line 1. 

Những gì tôi đã không tìm ra lý do tại sao là nó phù hợp với ololololo.

Các vấn đề liên quan