2012-06-14 19 views
5

der Suche nach einem Perl-Einzeiler, was alle Worte mit dem nächsten Muster finden:Suche Worte mit jedem Wiederholungs Zeichen

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

für ein Zeichen, es ist leicht, z.B. für 'a'

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

aber ich möchte für ANY Zeichen suchen, so, für einen regulären Ausdruck der Suche nach der Suche nach alle Wörter wie:

azalea #repeating a 
baobab #repeating b 
cyclic #c 

und so weiter ..

versuchte dies:

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

funktioniert aber nicht.

Antwort

6
(?:(?!STRING).) 

ist

(?:STRING) 

als

[^CHAR] 

, ist

CHAR 

so konnte man

verwenden
3

Dies ist die beste Regex ich einfiel:

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

auf RegexPal getestet.

0

Sie auch einen faulen Quantifizierer mit einem Atom nicht-Rückzieher Gruppe verwenden:

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

Altho, die nur funktioniert, wenn 0 Zwischen Zeichen akzeptabel ist.

mit mindestens 1 Charakter würden Sie eine negative Lookahead verwenden müssen:

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

In perlretut es sagt, dass man in einem regex (nicht der richtige Teil einer Substitution) mit \g1 Rückreferenzierung können. Dies wurde in 5.14 geändert. Da ich nur 5.12.2 habe, muss ich stattdessen \1 verwenden.

Daher Ihre ursprüngliche regex mit einem winzigen adjustion für mich gearbeitet:

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; 
} 

es sucht mit YAPE::Regex::Explain

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

ergibt:

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 
---------------------------------------------------------------------- 

bearbeiten: Ihre Einliner ist daher perl -e 'print if m/^([a-z])[^\1]+\1[^\1]+\1$/i'.

$ 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. 

Was ich herausgefunden haben, nicht der Fall ist, warum es ololololo Spiele:

Auf einer anderen Anmerkung, wenn Sie versucht hatte perl -w -e 'print if m/(as)$1/' Sie Ihr Problem hätte sofort gesehen.

Verwandte Themen