2012-03-06 4 views
0

Quelqu'un peut-il s'il vous plaît laissez-moi savoir le Regex utilisé pour trouver des nombres qui est de multiples de 4 à partir d'une chaîne donnée. La chaîne comprendra à la fois du texte et des chiffres.Regex pour trouver des nombres qui sont des multiples de 4 à partir d'un ensemble donné de nombres?

Merci d'avance

+1

Quelqu'un peut-il s'il vous plaît laissez-moi savoir quelle taille tournevis à utiliser pour marteler dans un clou? Utilisez le bon outil pour le travail! – Johnsyweb

Répondre

1

Avec regex, vous ne pouvez extraire que des nombres entiers. Cependant, il est possible d'extraire uniquement les nombres pairs:

(\d*[02468]) 

Ensuite, vous devez les vérifier si elles sont divisibles avec 4 modulo test:

if ((number != 0) && (number % 4 == 0)) { 
    // number is dividable with 4 and does not equal 0 
} 
+0

probablement la meilleure solution, puisque vous ne pouvez pas avoir cette logique dans regex mais toujours considérer seulement les unités possibles avec elle –

+0

@ hsz Il peut retourner '34' de' 345'. – alhelal

2

Regex est pas le bon outil pour faire le emploi, mais si vous voulez vraiment, un essai avec:

/[[0268][048]|[13579][26])(\D|$)/ 
3

se plaindre de ne pas être regex l'outil pour le travail ne répond pas vraiment à la question et je pense est en quelque contre-productif. Bien qu'il soit peut-être vrai que le demandeur ignore tout simplement qu'il existe un meilleur moyen. Cependant, peut-être qu'il construit un lexeur pour un compilateur de langue entièrement nouveau qui prend seulement certains diviseurs comme des jetons?

Cela peut être peu probable et peu pratique, mais mon point est que porter un jugement sur un motif inférées ne fait pas que quelqu'un de bon ... Mais bon ...

Je pense que cela est une question intéressante si sans autre raison que cela présente un défi intéressant académiquement, et pour répondre à votre question il y a un moyen d'utiliser regex pour déterminer des multiples.

En fin de compte regex est juste un modificateur de modèle non? Alors, quels types de modèles pourraient être créés par des nombres en multiples de quatre? Pour répondre à cette question, j'ai écrit un programme rapide pour imprimer tous les multiples de quatre 1-500 (essayer;)

import java.io.FileWriter; 

public class Four { 
    public static void main(String args[]){ 
     StringBuilder myFour = new StringBuilder(); 
     int i = 1; 
     int mult = 0; 
     while(mult < 500){ 
      mult = i*4; 
      myFour.append(mult + "|"); 
      i++; 
     } 
     try{ 
      FileWriter writer = new FileWriter("out.txt"); 
      writer.write(myFour.toString()); 
      writer.close(); 
     } catch(Exception e){e.printStackTrace();} 
    } 
} 

ce que j'ai remarqué est que le dernier chiffre de chaque nombre alternait entre 0 4 8 2 6. Maintenant, vous pourriez être tenté de l'utiliser immédiatement et vérifier toutes les chaînes de chiffres pour voir si elles se terminent dans l'un de ces nombres, mais cela ne fonctionnerait pas, car d'autres entiers se terminent également avec ces chiffres qui ne sont pas eux-mêmes divisibles par quatre tels que 10, 14, 18, 22, 26, etc ... et ainsi la recherche continue. Ensuite, j'ai regardé les deux derniers chiffres et j'ai remarqué une répétition entre 0 et 100

4 | 8 | 12 | 16 | 20 | 24 | 28 | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | 64 | 68 | 72 | 76 | 80 | 84 | 96 | 100 | ... | 204 | 208 | 212 | ...

si vous préfixez les chiffres simples avec des zéros, vous remarquerez que ce modèle répète chaque incrément de 100. Alors maintenant je me sens assez confiant que je suis sur quelque chose. Pour tester ma théorie plus loin j'ai tiré vers le haut de Google et tapé 2147483648% 4 (qui est le prochain nombre le plus élevé après la valeur maximale signée de 32 bits divisible par 4) c'était juste la première valeur arbitraire qui vient à l'esprit et n'a pas autre sens que je suis conscient de et comme il se trouve 2147483648% 4 = 0 alors je me sens vraiment bien en ce moment. Je suppose que vous pourriez réellement écrire une preuve mathématique et prouver que cette théorie fonctionne, mais je suis plus en application. Donc, je me rends compte à ce stade que tout ce que j'ai à faire est d'écrire cette regex et ensuite je peux le tester par rapport à la sortie du programme écrit ci-dessus. Donc, mon prochain objectif est d'écrire la regex réelle.

Si vous remarquez que j'ai fait de façon pratique le programme imprimer l'opérateur regex OU, donc je peux juste couper et coller la plupart des regex et je suis à mi-chemin de la maison.Tout ce que je veux sont les deux derniers chiffres de sorte que la première partie de mon regex ressemble à ceci:

(00|04|08|12|16|20|24|28|32|36|40|44|48|52|56|60|64|68|72|76|80|84|88|92|96) 

vous remarquerez que je préfixés les zéros à un seul chiffre et ajouté 00 à l'avant. Encore une fois c'est parce que je veux faire correspondre les deux derniers caractères, y compris le 00 de 100 (cela retournera aussi des chaînes de 0 comme un multiple valide de quatre comme il se doit). alors maintenant j'ai mon suffixe regex wrtten. Selon ma théorie, toute chaîne de chiffres suffixée par les deux chiffres susmentionnés est un multiple de quatre, donc j'ai juste besoin d'écrire une règle pour le préfixe (n'importe quel chiffre) et j'ai terminé. Ceci est très facile et est juste [0-9] * Alors maintenant, mon regex ressemble à ceci:

[0-9]*(00|04|08|12|16|20|24|28|32|36|40|44|48|52|56|60|64|68|72|76|80|84|88|92|96) 

Maintenant, je suis presque fait. Qu'ai-je oublié? Chiffres uniques !!! 0,4 et 8 seront rejetés par la regex ci-dessus, car ils sont à un seul chiffre et le modèle ci-dessus ne correspond qu'à deux chiffres précédés de 0 ou plusieurs chiffres. donc je dois modifier l'expression régulière un peu et je me retrouve avec ceci:

(0|4|8)|([0-9]*(00|04|08|12|16|20|24|28|32|36|40|44|48|52|56|60|64|68|72|76|80|84|88|92|96)) 

et c'est à peu près tout. Techniquement, vous devrez également ajouter des limites de mots puisque vous voulez traiter toute la chaîne de chiffres comme un mot. vous ajouteriez des balises de délimitation comme ceci:

\b(0|4|8)|([0-9]*(00|04|08|12|16|20|24|28|32|36|40|44|48|52|56|60|64|68|72|76|80|84|88|92|96))\b 

mais cela dépend de votre application. Si vous utilisiez ceci dans une lexique, vous pourriez construire avec jflex par exemple, vous ne voudrez peut-être pas les inclure puisque vous pourriez avoir d'autres règles pour des lexèmes similaires.

Donc dans l'ensemble c'est comme ça que je le ferais. Ce n'est probablement pas la regex la plus courte et la plus concise et je suis sûr qu'il y a de meilleures façons de le faire, mais si vous cherchez quelque chose de rapide et sale, je ne pense pas que ça devienne plus rapide ou plus sale. En outre, j'ai pensé que cela pourrait m'aider si je vous ai expliqué mon processus de pensée. L'inconvénient d'être rapide et sale est que je pourrais avoir entièrement tort et si oui maintenant vous pouvez voir exactement où j'ai été déraillé et vous pouvez remettre le train sur les rails vous-même;) J'espère que cela aide ....

Questions connexes