Update: It does work when I get the syntax of the negative lookahead assertion correct. (?!...) not (?!=...)!
Try this:
perl -nle"/^(.)(?!\1)(.)(?!\1|\2)(.)(?!\1|\2|\3)(.)(?!\1|\2|\3|\4)(.)\ +3(?!\1|\2|\3|\4|\5)(.)(?!\1|\2|\3|\4|\5|\6).$/ and print" <words
Expanded out that regex is:
/^ ## With the $, exactly 8 chars only (.) ## Any char as \1 (?!\1)(.) ## Any char as \2 except \1 (?!\1|\2)(.) ## Any char as \3 except \1 or \2 (?!\1|\2|\3)(.) ## Any char as \4 except ... (?!\1|\2|\3|\4)(.) ## Any char as \5 except ... \3 ## Only whatever is in \3 (?!\1|\2|\3|\4|\5)(.) ## Any char as \6 except ... (?!\1|\2|\3|\4|\5|\6). ## Any char except any char we've alre +ady seen $/x
That begs to be generated from some kind of shorthand spec. and actually, you used such a spec in your question.
'ABCDECFG' is a perfect spec. once you think of those letters as placeholders rather than literal characters.
Update: And here is a generator:
#! perl -slw use strict; my $spec = shift or die 'No spec supplied!'; my $re = ''; my %tally; my $i = 1; for my $c ( split '', $spec ) { if( exists $tally{ $c } ) { $re .= '\\' . $tally{ $c }; } else { if( $i == 1 ) { $re .= '(.)'; } else { $re .= '(?!' . join( '|', map{ '\\' . $_ } values %tally ) . ')(.)'; } $tally{ $c } = $i++; } } $re = qr[^$re$]; print $re; m[$re] and printf $_ while <>; __END__ C:\test>wordSolver ABCDECFG words (?-xism:^(.)(?!\1)(.)(?!\1|\2)(.)(?!\1|\3|\2)(.)(?!\1|\4|\3|\2)(.)\3(? +!\1|\4|\3|\5|\2)(.)(?!\6|\1|\4|\3|\5|\2)(.)$) abednego abscised airborne ... whisking worker's writhing ziegfeld
I wonder if the golfers could reduce that to a one-liner?
In reply to Re: Regex help
by BrowserUk
in thread Regex help
by Anonymous Monk
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |