LoginSignup
23
24

More than 1 year has passed since last update.

整数, 小数, 浮動小数点数の正規表現

Last updated at Posted at 2016-05-20

概要

シェルを使って数値データファイルの整形を行っている際,正規表現で詰まったのでメモ代わりに.
整数(1,2,3,...)と小数(1.1,2.5,...)と浮動小数点数(1.0E+10, 1.6e-19, ...)が入り混じったファイルから数値を抜き出す正規表現.

正規表現

以下の様な正規表現で抜き出せた.
[+-]?[0-9]+[\.]?[0-9]*[eE]?[+-]?[0-9]*
実際にはこれをgrepなりegrepなりに突っ込んで抜き出す.

コメントでいただいた指摘を受けた追記について

2016/8/30追記
@hikozaru_3 さんより,上の正規表現だと1+15-2のようなケースもマッチしてしまうという指摘がありました.
以下の正規表現が望ましいです.
[+-]?[0-9]+[.]?[0-9]([eE][+-])?[0-9]

また,これに併せてテスト用のスクリプトを修正したため,今まで記載していたセクションの下に修正後のものを追記します.

2017/6/22追記
@scivola さんより,1e+のような「指数もどき」もマッチしてしまうという指摘がありました.
上のものよりも以下のもののほうが望ましいかと思われます.
[+-]?[0-9]+(\.[0-9]*)?([eE][+-]?[0-9]+)?

こちらの正規表現でのテスト結果ですが,現在多忙につき割愛(もしくは後日改めて追記)させていただきます...:cry:

2018/12/2追記
.123のような小数点以下のみで数値を表現している場合は
[+-]?([0-9]+(\.[0-9]*)?|\.[0-9]+)([eE][+-]?[0-9]+)?
となるようです.
@Nabetani さんありがとうございます!!
テスト結果も編集しました.今あらためて見ると少し気持ち悪い結果もありますね。

以前のコード

例(正規表現にミスあり)

テスト用のスクリプト. egrep-oオプションで条件に一致した部分だけを出力する.

testscript
#!/bin/bash
file=$1

for line in `cat ${file}`
do
    echo ${line}
    N=`echo ${line} | egrep -o '[+-]?[0-9]+[\.]?[0-9]*[eE]?[+-]?[0-9]*'`
    echo "result = ${N}"
done

で、これにこんな感じのテストケースを放り込む

testcase
1
58
-5
2.8
-3.39
73.098abh
1.0e+29
1.6E-16
abc39
num=395479.27

で、実行結果

result
>./numtest.sh testfile.txt
1
result = 1
58
result = 58
-5
result = -5
2.8
result = 2.8
-3.39
result = -3.39
73.098abh
result = 73.098
1.0e+29
result = 1.0e+29
1.6E-16
result = 1.6E-16
abc39
result = 39
num=395479.27
result = 395479.27

正しく数値だけ抜き出せてると思う

例(2018/12/2修正版)

というわけで修正したシェルスクリプトです.

testscript
#!/bin/bash
file=$1

for line in `cat ${file}`
do
    echo ${line}
    N=`echo ${line} | egrep -o '[+-]?([0-9]+(\.[0-9]*)?|\.[0-9]+)([eE][+-]?[0-9]+)?'`
    for res in $N
    do 
        echo "result = ${res}"
    done
done

これに併せてテストケースも増やしました.今回は1つの行に複数の数値があった場合も対応できるようにしています.

testcase
1
58
-5
2.8
-3.39
73.098abh
1.0e+29
1.6E-16
abc39
num=395479.27
1+1
234gh290
432-84
235hk23.4e-6
1e+
3e-
.123
.23h5
hoge

以下,結果.

result
1
result = 1
58
result = 58
-5
result = -5
2.8
result = 2.8
-3.39
result = -3.39
73.098abh
result = 73.098
1.0e+29
result = 1.0e+29
1.6E-16
result = 1.6E-16
abc39
result = 39
num=395479.27
result = 395479.27
1+1
result = 1
result = +1
234gh290
result = 234
result = 290
432-84
result = 432
result = -84
235hk23.4e-6
result = 235
result = 23.4e-6
1e+
result = 1
3e-
result = 3
.123
result = .123
.23h5
result = .23
result = 5
hoge

今あらためて結果を確認すると、.23h5みたいなケースから.235が抜き出されるのは若干気持ち悪いですね...

23
24
8

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
24