10
votes

Regex pour les chiffres sur la notation scientifique?

Je charge un fichier .obj qui a des lignes comme

vn 8.67548e-017 1 -1.55211E-016

pour les normales de sommet. Comment puis-je les détecter et les apporter à la double notation?


0 commentaires

6 Réponses :


14
votes

Une regex qui fonctionnerait assez bien serait: xxx pré>

conversion à un numéro peut être effectué comme ceci: chaîne en notation scientifique C ++ à la double conversion , je suppose. p>

La regex est p>

-?      # an optional -
[\d.]+  # a series of digits or dots (see *1)
(?:     # start non capturing group
  e     # "e"
  -?    # an optional -
  \d+   # digits
)?      # end non-capturing group, make optional


6 commentaires

Je suggérerais de casser le [\ d.] + dans \ d + \. \ D + pour empêcher de fausses correspondances. Utilisez \ d * si vous n'avez pas besoin de chiffres avant et / ou après le point décimal.


Est-ce que cela ne va pas correspondre au 5.5.5.5.5.5.5.5.5.5.5.5.5


@Martin: Oui, c'est. La question est la suivante: une telle valeur est-elle susceptible de se produire? Si oui, la regex peut facilement être rendue plus précise. Je suppose que le scénario 5.5.5.5 est plutôt improbable dans ces circonstances.


(Je crois comprendre que c'est un très vieux commentaire, mais néanmoins) Y a-t-il une raison pour que vous ne puissiez pas opter pour l'option la plus valide, étant donné qu'il serait assez trivial de mettre en œuvre? Je ne peux pas imaginer que cela prendrait beaucoup de péage sur la performance et serait plus fiable ...?


La performance n'est même pas une considération ici. Il est tout simplement de sens de préparer une regex pour une affaire qui ne se produira pas avec des données valides. On ne peut pas anticiper toutes les formes de données non valides de toute façon, ce qui rend la dégoût plus complexe "juste parce que" est une perte de temps. Si 5.5.5.5.5.5 devrait se produire dans l'entrée (ou si cela vous fait sentir mieux), par tous les moyens, adaptez la regex. ;)


-? [\ d.] + (?: [E | E | D | D] -? \ D +)? peut correspondre presque tout.



3
votes

Vous pouvez identifier les valeurs scientifiques en utilisant: -? \ d * \.? \ d + e [+ -]? \ d + regex.


3 commentaires

N'utilisez jamais {0,1} -Utiliser ? à la place. Le premier est plus long, pas plus clair et a un effet identique.


{0,1} peut être remplacé par ? . Mais pourquoi voudriez-vous que le point décimal soit facultatif? Et cela ne permet pas de chiffrer les nombres négatifs. Il correspond également faussement .0 qui n'est probablement pas souhaité.


@margren: Probablement parce que, selon l'exemple de données, le point décimal est facultatif. Le troisième champ est simplement "1".



3
votes

Le Fonction de bibliothèque standard strtod poignées Le composant exponentiel juste bien (donc atof , mais strtod vous permet de différencier entre une analyse échouée et l'analyse de la valeur zéro).


0 commentaires

2
votes

Si vous pouvez être sûr que le format du double est scientifique, vous pouvez essayer ce qui suit: xxx

si vous souhaitez détecter s'il existe un nombre de points flottant de cette Format, puis les regexnes ci-dessus feront le tour.

EDIT: Le manipulateur scientifique n'est pas nécessaire, lorsque vous diffusez dans un double, il effectuera automatiquement la manipulation de vous (que ce soit fixe ou scientifique)


1 commentaires

Je pense que c'est la voie à suivre pour C ++. Trouble avec des regèex qui travaillent parfois et parfois ne serait pas le moyen idéal pour moi. Cela déléguait plutôt la partie approximative de STL Stringstream. Ceci est la version de niveau supérieur de la vérification d'un format scientifique valide.



0
votes

Eh bien, ce n'est pas exactement ce que vous avez demandé car ce n'est pas Perl (gak) et c'est une définition régulière et non une expression régulière, mais c'est ce que j'utilise pour reconnaître une extension des littéraux en points flottants (l'extension est Permettre à "_" dans les chaînes de chiffres), je suis sûr que vous pouvez le convertir en une réégyvabilité illisible si vous le souhaitez:

/* floats: Follows ISO C89, except that we allow underscores */
let decimal_string = digit (underscore? digit) *
let hexadecimal_string = hexdigit (underscore? hexdigit) *

let decimal_fractional_constant =
  decimal_string '.' decimal_string?
  | '.' decimal_string

let hexadecimal_fractional_constant =
  ("0x" |"0X")
  (hexadecimal_string '.' hexadecimal_string?
  | '.' hexadecimal_string)

let decimal_exponent = ('E'|'e') ('+'|'-')? decimal_string
let binary_exponent = ('P'|'p') ('+'|'-')? decimal_string

let floating_suffix = 'L' | 'l' | 'F' | 'f' | 'D' | 'd'
let floating_literal =
  (
    decimal_fractional_constant decimal_exponent? |
    hexadecimal_fractional_constant binary_exponent?
  )
  floating_suffix?


0 commentaires

5
votes

J'ai essayé un certain nombre d'autres solutions en vain, je suis donc proposé cela.

       ^(-?\d+)\.?\d+(e-|e\+|e|\d+)\d+$


2 commentaires

J'ai adapté cette réponse et j'ai proposé avec ^ (?: -? \ D *) \.? \ D + [ee] [- \ +]? \ D + $ - Permet des cas comme .1E5 qui sont valides dans JS


Pourquoi avez-vous terminé le deuxième groupe de capture avec \ d + ? Il rend votre regex attrape des numéros de notation non scientifiques comme 3.1415 .