2010-11-24 11 views
0

Je recherche une expression rationnelle qui correspond à des chaînes d'une longueur donnée (paramétrée) commençant par "+" ou une lettre minuscule. Il doit en outre contenir au moins une lettre majuscule suivie d'un chiffre et ne doit pas se terminer par un chiffre. Entre les deux, il peut y avoir des lettres majuscules et minuscules ainsi que des chiffres [a-zA-Z0-9]. Cette chaîne peut faire partie d'une chaîne plus grande.RegEx pour vérifier la chaîne avec une longueur donnée contenant une séquence spéciale

J'ai des difficultés à implémenter la restriction de longueur. J'ai essayé de le résoudre avec un lookahead mais ça ne marchera pas. Disons que la longueur de la chaîne est 10:

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

Lengtt 10:

Ces exemples de chaînes doivent être présents:

c4R9vMh0Lh

+ lKj9CnR5x

Ces exemples de chaînes ne doivent pas être identiques:

9kR7alcjaa

+ 5kl9Rk9XZ

aBikJ6clo9

Longueur de 4:

Ces exemples de chaînes doivent être adaptées:

aR3v

+ K7Z

Ces exemples chaînes ne doivent pas être présents:

9R3v

+ 7KZ

aK79

Pouvez-vous me donner quelques conseils ?

+1

Nous ne sommes pas ici pour résoudre les devoirs, mais cela aidera: http://gskinner.com/RegExr/ –

+0

Pourquoi avez-vous considère mon problème "devoirs"? – bin4ry

+1

Pouvez-vous fournir comme 5 tests? Pour une raison quelconque, je suis trop cérébral pour les générer, mais je trouve que je suis assez cohérent pour écrire une regex (allez figure) ** EDIT ** Aussi, s'il vous plaît inclure un couple qui ne devrait pas passer (mais peut être proche –

Répondre

2

Type d'une exigence étrange, mais cela semble faire ce que vous voulez:

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

Après avoir établi le premier caractère de la manière normale, il utilise un test avant de vérifier la longueur et les exigences de cohérence de base (toutes les lettres et chiffres , ne se termine pas avec un chiffre). Tout ce qui correspond au lookahead est capturé dans le groupe # 1.

Ensuite, en recommençant à partir de la position qui suit le premier caractère, un autre lookahead vérifie la condition la plus spécifique: une lettre majuscule suivie d'un chiffre. Si cela réussit, la référence arrière (\1) continue et consomme les caractères qui ont été capturés dans le premier lookahead.

Le paramétrage de l'expression régulière consiste simplement à remplacer les nombres à l'intérieur des accolades par des nombres ou des expressions en fonction de la longueur souhaitée. Voici un exemple en Java: Sortie

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

exemple:

 
>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

C'est juste merveilleux. Merci beaucoup pour votre aide. Ton regex est assez ingénieux. Bon premier avènement! – bin4ry

1

Votre exemple utilise un regard négatif au lieu de positif, utilisez plutôt ^(?=.{10,}). Cela devrait fonctionner aussi longtemps que vos appuis de regex vont bien sûr de l'avant. À mon avis, des situations comme celle-ci sont souvent meilleures avec l'utilisation de plus d'une regex, mais ce n'est pas toujours une option.

+0

Oui, vous avez raison. De plus, j'ai peut-être besoin de trouver cette chaîne correspondant à l'intérieur d'une plus grande chaîne environnante. Par conséquent^et $ peut-être mal et je l'ai retiré de mon exemple ci-dessus. Maintenant, quand j'utilise (? =. {10}) [az \ +] [a-zA-Z0-9] * ([AZ] [0-9]) + [a-zA-Z0-9] * [un -zA-Z] il ne correspond pas à 10 caractères de long mais à des plus gros. – bin4ry

0

Ce:

#!/usr/bin/perl 

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

génère ce:

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

Alors que ceci:

$_ = <<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"; 

produit ceci:

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