8
votes

Comment faire correspondre une longue avec Java Regex?

Je sais que je peux correspondre aux numéros avec motif.comple ("\\ d *");

mais il ne gère pas les longues valeurs min / max. < p> Pour les problèmes de performance liés aux exceptions, je ne veux pas essayer d'analyser la longue sauf si c'est vraiment un long. xxx

je veux dire que je ne veux pas d'essayer / attraper bloc et je ne veux pas faire des exceptions soulevées pendant une longue comme « 564654954654464654654567879865132154778 » qui est de la taille d'une longue Java régulière. quelqu'un Finalité

a un modèle pour gérer ce genre de besoin pour la primitive types Java? Le JDK fournit-il quelque chose à le gérer automatiquement? Y a-t-il un mécanisme d'analyse sans danger dans Java?

Merci


EDIT: S'il vous plaît supposer que la "mauvaise chaîne longue" n'est pas un cas exceptionnel. Je ne demande pas de repère, je suis ici pour une regex représentant une longue et rien de plus. Je suis au courant du temps supplémentaire requis par la vérification des regex, mais au moins ma longue analyse sera toujours constante et ne sera jamais dépendante du% des "mauvaises chaînes"

Je ne trouve pas le Link à nouveau mais il y a une belle analyse d'analyse sur Stackoverflow, ce qui montre clairement que la réutilisation de la regex compilée Sams est vraiment rapide, beaucoup plus rapide que de jeter une exception, ce n'est donc qu'un petit seuil d'exceptions qui rendrait le système plus lentement que par la vérification de la regex supplémentaire. .


3 Réponses :


1
votes

Catchez simplement la formatException, à moins que ce cas ne se produise très souvent.

Une autre manière serait d'utiliser un motif qui permet uniquement de longues littérales. Un tel motif pourrait être assez complexe.

Une troisième voie serait d'analyser le nombre comme de la première fois. Ensuite, vous pouvez le comparer à long.max_value et long.min_value pour vérifier si elle est dans les limites de long. Cependant, cela pourrait être coûteux aussi.

Notez également: L'analyse longue est assez rapide, c'est une méthode très optimisée (que, par exemple, essaie d'analyser deux chiffres en une seule étape). L'application de la correspondance des motifs peut être encore plus coûteuse que d'analyser l'analyse. La seule chose qui est lente à propos de l'analyse consiste à lancer la nobleFormeXception. Ainsi, simplement attraper l'exception est la meilleure façon d'aller si le cas exceptionnel n'arrive pas trop souvent



14
votes

Le minimum avlue d'un long est -9,223,372,036,854,775 808 et la valeur maximale est 9,223,372,807 . Donc, un maximum de 19 chiffres. Ainsi, \ d {1,19} devrait vous y arriver, peut-être avec un - , et avec ^ et $ < / code> pour correspondre aux extrémités de la chaîne.

SO grossièrement : xxx

... ou quelque chose le long de ces lignes, et en supposant Vous ne laissez pas les virgules (ou les avez déjà supprimés).

Comme le souligne Gexicide dans les commentaires, ce qui précède permet une petite gamme de valeurs non valides (en comparaison), telles que 9 999 9999999999999999999999999,999 / code>. Vous pouvez obtenir plus complexe avec votre regex ou simplement accepter que ce qui précède éliminera la grande majorité des nombres invalides et que vous réduisez ainsi le nombre d'exceptions d'analyse que vous obtenez.


7 commentaires

Pas vrai, votre modèle permet le numéro 9 999 9999999999999999999, qui n'est pas à la longue portée


@GoxxIDE: True, un peu de réglage peut être nécessaire. Il serait au moins très vaste réduire le nombre d'exceptions.


Bien sûr, mais je suppose que OP veut une solution correcte. Mais je suis d'accord, le motif filtre déjà le plus mauvais cas.


merci, c'est ce que je pensais aussi -> limiter le nombre de chiffres


pouvez-vous expliquer le "-" s'il vous plaît je ne trouve pas cela dans le modèle Javadoc


@Sebastienlorber: le - est un - (pour permettre des nombres négatifs), c'est pourquoi vous ne l'avez pas trouvé dans Javadoc. :-) Le ? après cela signifie "zéro ou une fois" (qui est dans le Javadoc). E.g., ? est un raccourci pour {0,1} .


Oooh merci je suis stupide ^^ mais je veux juste que je veux juste des valeurs positives alors je ne pensais pas à - comme le long signe



3
votes

Cette expression régulière devrait faire ce dont vous avez besoin:

^ (- 9223372036854775808 | 0) $ | ^ (((-?) ((?! 0) \ D {1,18} | [1-8] \ D {18} | 9 [0- 1] \ d {17} | 92 [0-1] \ d {16} | 922 [0-2] \ D {15} | 9223 [0-2] \ D {14} | 92233 [0-6] \ D {13} | 922337 [0-1] \ d {12} | 92233720 [0-2] \ D {10} | 922337203 [0-5] \ D {9} | 9223372036 [0-7] \ D {8} | 92233720368 [0-4] \ D {7} | 922337203685 [0-3] \ D {6} | 9223372036854 [0-6] \ D {5} | 92233720368547 [0-6] \ D {4 } | 922337203685477 [0-4] \ D {3} | 9223372036854775 [0-7] \ D {2} | 922337203685477580 [0-7])) $

mais cette refente ne valide pas les symboles supplémentaires tels que + , l , _ et etc. Et si vous devez valider tout ce qui est possible. Valeurs longues dont vous avez besoin pour mettre à niveau cette REGEXP.


0 commentaires