특정 문자열이 부동 소수점인지 확인하는 방법은 무엇입니까? 이는 부동 소수점으로 가능합니다.
12.245
+.0009
3.11e33
43.1E11
2e-14
내가 시도한 것은 다음과 같습니다.
grep "^[+\-\.0-9]"
grep "^[+-]*[0-9]"
grep "^[+\-\.0-9]"
다른 관련 내용이 많이 있지만 전혀 필터링되지 않습니다. 거의 모든 문자열이 교차됩니다. 이 문제를 어떻게 해결할 수 있나요?
답변1
grep -xE '[-+]?[0123456789]*\.?[0123456789]+([eE][-+]?[0123456789]+)?'
를 사용하여 -x
줄의 시작과 위치에 정규식을 고정하므로 줄의 어느 곳에서나 패턴이 발견되는 것이 아니라 줄이 전체 패턴과 일치해야 합니다.
지원되는 모든 항목을 일치시키려면POSIX/Cstrtod()
이 유틸리티의 많은 구현에서 인식되는 바와 같이 printf
예를 들면 다음과 같습니다.
r=[$(locale decimal_point)]
d=[0123456789]
h=[0123456789abcdefABCDEF]
grep -xE "[[:space:]]*[-+]?($d*$r?$d+([eE][-+]?$d+)?|\
0[xX]$h*$r?$h*([pP][-+]?$d+)?|\
[iI][nN][fF]([iI][nN][iI][tT][yY])?|\
[nN][aA][nN]|\
NAN\([abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]+\))"
0x3f, 0xFP-4, -Infinity, NAN(무엇이든)과 같은 것들도 마찬가지입니다.
$ printf '%g\n' 0x3f 0xFp-4 -Infinity 'NAN(whatever)'
63
0.9375
-inf
nan
답변2
선택하다파이썬솔루션(용더 적은복잡한 입력):
샘플 input.txt
파일:
11
12.245
+.0009
---0
3.11e33
43.1E11
2e-14
t12
aaa
10.001
check_float.py
스크립트:
import sys
with open(sys.argv[1], 'r') as inp:
f = 'No'
for l in inp.read().splitlines():
try:
if float(l) and '.' in l: f = 'Yes'
except ValueError:
f = 'No'
finally:
print '{0} - {1}'.format(l, f)
용법:
python check_float.py input.txt
산출:
11 - No
12.245 - Yes
+.0009 - Yes
---0 - No
3.11e33 - Yes
43.1E11 - Yes
2e-14 - Yes
t12 - No
aaa - No
10.001 - Yes
답변3
면책조항: 이는 불완전한 솔루션입니다. Perl의 Scalar::Util::looks_like_number()
기능은 이를 수행하는 최선의 루틴 선택이 아닐 수도 있습니다. 바라보다Stéphane Chazelas는 아래에 댓글을 달았습니다..
누군가 그것을 보고 뭔가를 고르고 싶다면 coproc
여기에 남겨 두겠습니다.
가능한 많은 부동 소수점 형식과 일치하도록 자신만의 정규 표현식을 작성하는 대신 이미 구현된 라이브러리를 사용하십시오.
perl -MScalar::Util -ne 'exit !Scalar::Util::looks_like_number($_)'
bash
쉘 함수 로서 :
is_number () {
perl -MScalar::Util -ne 'exit !Scalar::Util::looks_like_number($_)' <<<"$1"
}
is_number hello && echo 'hello is a number'
is_number 1.234 && echo '1.234 is a number'
bash
공동 프로세스 로 (숫자를 테스트할 때마다 Perl 프로세스를 시작하지 않기 위해):
coproc PERLIO=:raw perl -MScalar::Util -ne \
'print Scalar::Util::looks_like_number($_) ? "Yes" : "No", "\n"'
while IFS= read -r -p 'Number please: ' possnum; do
printf '%s\n' "$possnum" >&${COPROC[1]}
read -u ${COPROC[0]}
case "$REPLY" in
Yes) printf '%s is a number\n' "$possnum" ;;
No) printf '%s is _not_ a number\n' "$possnum" ;;
esac
done
kill "$COPROC_PID"
또는 두 가지를 결합합니다.
coproc PERLIO=:raw perl -MScalar::Util -ne \
'print Scalar::Util::looks_like_number($_) ? "Yes" : "No", "\n"'
is_number () {
printf '%s\n' "$1" >&${COPROC[1]}
local REPLY
read -u ${COPROC[0]}
[ "$REPLY" = 'Yes' ] && return 0
return 1
}
while IFS= read -r -p 'Number please: ' possnum; do
if is_number "$possnum"; then
printf '%s is a number\n' "$possnum"
else
printf '%s is a _not_ a number\n' "$possnum"
fi
done
kill "$COPROC_PID"