Extraindo números de ponto flutuante positivos / negativos de uma string

3

Estou tentando extrair números de algum texto. Atualmente estou usando o seguinte:

echo "2.5 test. test -50.8" | tr '\n' ' ' | sed -e 's/[^0-9.]/ /g' -e 's/^ *//g' -e 's/ *$//g' | tr -s ' '

Isso me daria 2,5 "." e 50,8. Como devo modificar o primeiro sed para que ele detecte números flutuantes, positivos e negativos?

    
por ahajib 20.06.2016 / 21:28

2 respostas

6

grep funciona bem para isso:

$ echo "2.5 test. test -50.8" | grep -Eo '[+-]?[0-9]+([.][0-9]+)?'
2.5
-50.8

Como funciona

  • -E

    Use regex estendido.

  • -o

    Retorna apenas as correspondências, não o contexto

  • [+-]?[0-9]+([.][0-9]+)?+

    Corresponder números identificados como:

    • [+-]?

      Um sinal principal opcional

    • [0-9]+

      Um ou mais números

    • ([.][0-9]+)?

      Um período opcional seguido por um ou mais números.

Obtendo a saída em uma linha

$ echo "2.5 test. test -50.8" | grep -Eo '[+-]?[0-9]+([.][0-9]+)?' | tr '\n' ' '; echo ""
2.5 -50.8
    
por 20.06.2016 / 21:41
2

Uma solução grep :

$ echo "2.5 test. test -50.8" | tr ' ' '\n' | grep -E '^[+-]?[0-9]*\.?([0-9]+)$'
2.5
-50.8
  • O tr apenas converte a linha em várias linhas, substituindo os espaços por novas linhas.

  • O comando grep procura cadeias de caracteres que iniciam com um opcional + ou - , possivelmente seguido por alguns dígitos e um ponto decimal opcional. Então, precisamos de alguns dígitos no final.

Isso permitirá que coisas como 00000123.91288000 pareçam estranhas. Este é um número que queremos filtrar ou não? Tecnicamente é um número de ponto flutuante, apenas estranhamente formatado.

EDITAR : Para corretamente verificar números, não escreva sua própria expressão regular! Use uma rotina de biblioteca de algum lugar confiável.

No meu caso, eu usaria o pacote Scalar::Util do Perl, que tem uma conveniente looks_like_number() sub-rotina:

$ echo "2.5 test. test -50.8" | tr ' ' '\n' | perl -MScalar::Util -ne 'Scalar::Util::looks_like_number($_) && print'
2.5
-50.8

Isso tem o benefício adicional de encontrar números em outros formulários, como 1e3 .

    
por 20.06.2016 / 22:13