Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

概要

シェルを使って数値データファイルの整形を行っている際,正規表現で詰まったのでメモ代わりに.
整数(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が抜き出されるのは若干気持ち悪いですね...

hitsumabushi845
働きマン。ここでは業務/趣味まぜこぜでいろいろ書けるといいな。
http://hitsumabushi845.hatenablog.com/
works-hi
「はたらく」を楽しく!に向けて大手企業の人事業務から変えていく HR業界のリーディングカンパニー
https://www.works-hi.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away