2010-11-24 5 views
0

Ich suche nach einer Regex, die Strings mit einer gegebenen Länge (parametrisiert) findet, die mit "+" oder einem Kleinbuchstaben beginnen. Es muss zusätzlich mindestens einen Großbuchstaben gefolgt von einer Ziffer enthalten und darf nicht mit einer Ziffer enden. Dazwischen können Groß- und Kleinbuchstaben sowie Ziffern [a-zA-Z0-9] stehen. Diese Zeichenfolge kann Teil einer größeren Zeichenfolge sein.RegEx, um nach einer Zeichenfolge mit gegebener Länge zu suchen, die eine spezielle Sequenz enthält

Ich habe Schwierigkeiten beim Implementieren der Längenbeschränkung. Versucht, es mit einem Lookahead zu lösen, aber es wird nicht funktionieren. Lassen Sie uns die Zeichenfolge sagen, Länge 10 sein soll:

(?!.{10,})[a-z\+][a-zA-Z0-9]*([A-Z][0-9])+[a-zA-Z0-9]*[a-zA-Z] 

Lengtt von 10:

Diese Beispiel Saiten abgestimmt werden soll:

c4R9vMh0Lh

+ lKj9CnR5x

Diese Beispielzeichenfolgen sollten nicht übereinstimmen:

9kR7alcjaa

+ 5kl9Rk9XZ

aBikJ6clo9

Länge von 4:

Diese Beispiel Saiten abgestimmt werden soll:

aR3v

+ K7Z

Diese Beispiel Strings sollte nicht zugeordnet werden:

9R3v

+ 7KZ

aK79

Können Sie mir einige Hinweise geben ?

+1

Wir sind hier keine Hausaufgaben zu lösen, aber dies wird dazu beitragen: http://gskinner.com/RegExr/ –

+0

Warum Sie tun Betrachte mein Problem "Hausaufgaben"? – bin4ry

+1

Können Sie 5 Tests bereitstellen? Aus irgendeinem Grund bin ich zu hirntot, um sie zu generieren, aber ich finde, ich bin kohärent genug, um eine Regex zu schreiben (gehe Abbildung) ** EDIT ** Auch, bitte ein Paar, das nicht passieren sollte (aber kann nah sein) –

Antwort

2

Art einer seltsamen Anforderung, aber dies scheint zu tun, was Sie wollen:

/[a-z+] 
(?=([A-Za-z0-9]{8}[A-Za-z])) 
(?=.{0,6}[A-Z][0-9]) 
\1 
/x 

Nach dem ersten Zeichen in der normalen Art und Weise übereinstimmt, verwendet es einen Look-Ahead die Länge und Grundkonsistenzanforderungen zu überprüfen (alle Buchstaben und Ziffern , endet nicht mit einer Ziffer). Was auch immer der Lookahead ist, wird in Gruppe 1 erfasst.

Anschließend beginnt ein anderer Lookahead, beginnend an der Position nach dem ersten Zeichen, die spezifischere Bedingung: ein Großbuchstabe, gefolgt von einer Ziffer. Wenn das gelingt, geht die Rückreferenz (\1) weiter und verbraucht die Zeichen, die im ersten Lookahead erfasst wurden.

Die Parametrisierung der Regex ist eine einfache Angelegenheit, die Zahlen innerhalb der Klammern durch Zahlen oder Ausdrücke zu ersetzen, die auf der gewünschten Länge basieren. Hier ist ein Beispiel in Java:

import java.util.regex.*; 

public class Test 
{ 
    public static void main(String[] args) throws Exception 
    { 
    String[] inputs = { 
     "c4R9vMh0Lh", 
     "+lKj9CnR5x", 
     "9kR7alcjaa", 
     "+5kl9Rk9XZ", 
     "aBikJ6clo9", 
     "aR3v", 
     "+K7Z", 
     "9R3v", 
     "+7KZ", 
     "aK79" 
    }; 

    int len = Integer.parseInt(args[0]); 
    String regex = "[a-z+]" + 
     "(?=([A-Za-z0-9]{" + (len-2) + "}[A-Za-z]))" + 
     "(?=.{0," + (len-4) + "}[A-Z][0-9])" + 
     "\\1"; 
    Pattern p = Pattern.compile(regex); 
    Matcher m = p.matcher(""); 
    System.out.println("length = " + len); 
    System.out.println("regex = " + p.pattern()); 
    for (String s : inputs) 
    { 
     System.out.printf("%n%12s : %b%n", s, m.reset(s).find()); 
    } 
    } 
} 

Beispielausgabe:

 
>java Test 4 
length = 4 
regex = [a-z+](?=([A-Za-z0-9]{2}[A-Za-z]))(?=.{0,0}[A-Z][0-9])\1 

    c4R9vMh0Lh : false 

    +lKj9CnR5x : true 

    9kR7alcjaa : true 

    +5kl9Rk9XZ : false 

    aBikJ6clo9 : true 

     aR3v : true 

     +K7Z : true 

     9R3v : false 

     +7KZ : false 

     aK79 : false 
+0

Das ist einfach wunderbar. Vielen Dank für deine Hilfe. Deine Regex ist ziemlich genial. Hab einen schönen ersten Advent! – bin4ry

1

Ihr Beispiel verwendet negatives Look-Ahead anstelle von positiv, verwenden Sie stattdessen ^(?=.{10,}). Dies sollte so lange funktionieren, wie Ihr Regex-Geschmack natürlich vorausblickt.

Meiner Meinung nach sind Situationen wie diese oft am besten, wenn mehr als 1 Regex verwendet wird, aber das ist nicht immer eine Option.

+0

Ja, du hast Recht. Zusätzlich muss ich vielleicht diese passende Saite innerhalb einer größeren umgebenden Saite finden. Daher ist^und $ vielleicht falsch und ich habe es aus meinem obigen Beispiel entfernt. Wenn ich nun (? =. {10}) [az \ +] [a-zA-Z0-9] * ([AZ] [0-9]) + [a-zA-Z0-9] * [a -zA-Z] es passt nicht zu 10 Zeichen langen Strichen, sondern zu größeren. – bin4ry

0

Dies:

#!/usr/bin/perl 

$_ = "Hello%20world%20how%20are%20you%20today"; 
print "<$1>" while m{ 
    \G ((?: [^%] | % \p{xdigit}{2})+) 
    (?: 
     (?<= \G .{5}) 
     |(?<= \G .{4}) 
     |(?<= \G .{3}) 
    ) 
}xg; 

Produziert dies:

<Hello> 
<%20wo> 
<rld> 
<%20ho> 
<w%20a> 
<re%20> 
<you> 
<%20to> 
<day> 

Während dies:

$_ = <<EOM; 
This particularly rapid, 
unintelligible patter, 
Isn't generally heard, 
and if it is it doesn't matter. 
EOM 

s/(\s)/sprintf("%%%02X", ord $1)/ge; 
print "$_\n\n"; 

produziert diese:

This%20particularly%20rapid,%20%0Aunintelligible%20patter,%20%0AIsn't%20generally%20heard,%20%0Aand%20if%20it%20is%20it%20doesn't%20matter.%0A 

<This> 
<%20pa> 
<rticu> 
<larly> 
<%20ra> 
<pid,> 
<%20> 
<%0Aun> 
<intel> 
<ligib> 
<le%20> 
<patte> 
<r,%20> 
<%0AIs> 
<n't> 
<%20ge> 
<neral> 
<ly%20> 
<heard> 
<,%20> 
<%0Aan> 
<d%20i> 
<f%20i> 
<t%20i> 
<s%20i> 
<t%20d> 
<oesn'> 
<t%20m> 
<atter> 
<.%0A> 
Verwandte Themen