2011-05-11 6 views
2

내가 할 그 라이브러리가 있다는 것을 알고펄에서 숫자의 유효성을 검사하는 방법은 무엇입니까?

사용 스칼라 :: 백분율 QW (looks_like_number);

아직 펄 정규 표현식을 사용하고 싶습니다. 그리고 정수로만 구성된 것이 아니라 두 배의 숫자로 작업하기를 원합니다.

그래서이

$ var에보다 더 나은 뭔가를 원하는 = ~/^ [+ -] \ D + $/

감사?.

+1

deimal number에는 선택 사항 (....)이있을 수 있습니다. 완전한 부분 후에. 최소한 당신은 조금이라도 노력했습니다. – Ingo

+0

나는 내 질문에 넣어 하나를 시도하고 그것을 (3.5)와 같은 숫자를 확인할 때 작동하지 않았다 예를 들어. –

+2

DID가 작동했습니다 - 패턴이 전체 문자열 "3.5" – Ingo

답변

14

숫자를 확인하기 위해 하나의 정규 표현식을 만드는 것은 정말 어렵습니다. 고려해야 할 기준이 너무 많습니다. Perlfaq4는 어떻게 스칼라인지 여부를 결정합니까 "섹션을 포함하는 수/전체/정수/부동

이 문서에서 코드는 다음의 시험을 보여줍니다?

if (/\D/)       {print "has nondigits\n"  } 
if (/^\d+$/)      {print "is a whole number\n" } 
if (/^-?\d+$/)      {print "is an integer\n"  } 
if (/^[+-]?\d+$/)     {print "is a +/- integer\n" } 
if (/^-?\d+\.?\d*$/)    {print "is a real number\n" } 
if (/^-?(?:\d+(?:\.\d*)?|\.\d+)$/) {print "is a decimal number\n"} 
if (/^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/) { 
    print "is a C float\n" 
} 
  • 첫 번째 시험은 자격을 상실를 부호없는 정수
  • 두 번째 테스트는 정수를 한정합니다.
  • 세 번째 테스트는 정수를 한정합니다.
  • 네 번째 테스트는 양수/음수 부호있는 정수를 정규화합니다.
  • 다섯 번째 테스트는 실수를 한정합니다.
  • 여섯 번째 테스트는 십진수를 규정합니다.
  • 일곱 번째 테스트는 c 스타일 과학 표기법으로 숫자를 한정합니다.

그렇다면이 테스트를 사용하는 경우 (첫 번째 테스트 제외) 하나 이상의 테스트가 통과하는지 확인해야합니다. 그럼 번호가 있어요.

다른 방법은 Scalar :: Util 모듈을 사용하고 싶지 않으므로 Scalar :: Util 코드에서 배울 수 있습니다. looks_like_number() 함수는 다음과 같이 설정 :

sub looks_like_number { 
    local $_ = shift; 

    # checks from perlfaq4 
    return $] < 5.009002 unless defined; 
    return 1 if (/^[+-]?\d+$/); # is a +/- integer 
    return 1 if (/^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/); # a C float 
    return 1 if ($] >= 5.008 and /^(Inf(inity)?|NaN)$/i) 
      or ($] >= 5.006001 and /^Inf$/i); 

    0; 
} 

당신은 당신의 상황에 적용 할 수있는 그 기능의 일부를 사용할 수 있어야합니다.

그러나 Scalar::Util은 핵심 Perl 모듈입니다. strict처럼 Perl과 함께 제공됩니다. 모든 것을 사용하는 것이 최선의 방법 일 것입니다.

+0

당신이 올린 기능은'look_like_number ('0 but true')'입력에 대한 출력과 다릅니다! – ikegami

+0

... 과부하 된 개체의 경우 오버로드 된 객체는 최신 릴리스의 Scalar :: Util :: PP에서 처리됩니다. PP 버전은 배포판의 최신 dev 릴리스에 더 이상 존재하지 않습니다. – ikegami

+0

예, Scalar-List-Utils-1.23에는 순수 Perl 버전이 있지만 Scalar-List-Utils-1.23_03에는없는 것으로 보입니다. CPAN의 v1.23 소스는 오버로드 된 객체를 처리하기 때문에 쉽게 읽을 수 있습니다. 그러나이 대화는 Scalar :: Util의 looks_like_number()가 이미 존재할 때 정규 표현식으로 새로운 일반화 된 숫자 한정 솔루션을 만드는 것이 어리석은 것이라는 점을 되풀이합니다. 보다 견고하고, 현대적이며, 유지 보수가 용이하다는 것은 거의 확실합니다. 또한 표준 Perl 배포판의 일부입니다. – DavidO

6

Regexp :: Common을 사용해야합니다. 대부분의 패턴은 알고있는 것보다 복잡합니다.

use Regexp::Common; 

my $real = 3.14159; 
print "Real" if $real =~ /$RE{num}{real}/; 

그러나, 패턴은 기본적으로 고정되지 않으므로 엄격한 버전은 다음과 같습니다

my $real_pat = $RE{num}{real}; 
my $real  = 3.14159; 
print "Real" if $real =~ /^$real_pat$/; 
+0

불행히도 Regexp :: Common은 정상적인 사람이 '1..2', '-1.0.2'및 '1.-2'와 같은 유효한 숫자 구문을 사용할 수 있다고 판단합니다. Scalar :: Util 접근 방식이 가장 좋은 방법이라고 주장하는 또 다른 사례입니다. – DavidO

+0

@DavidO 설명서에 일치하는 항목이 고정되어 있지 않음을 나타냅니다. 이 패턴들은 거기에 표시된대로 고정되어 있으면 실수와 일치하지 않습니다. 그들은 고정되어 있지 않으면 일치합니다. –

+0

아마도 더 강력한 정규 표현식을 유지하면서 게시물을 편집하는 것이 합리적 일 것입니다 :'m/^ $ RE {num} {real} $ /'. 나는 그것이 "1.-2"를 거부 할지를 시험하지 않았다. 나는 당신의 대답을 했어. – DavidO

0

그럼 먼저 당신이이 작업을 수행 할 수 있도록 수있는 쉼표를 포함하지 않는 것을 확인해야합니다 :

$ var = ~ s /, // g; # 모든 쉼표를 제거하십시오.

그런 다음 나머지 변수를 작성하여 비교 작업을 수행하십시오.

$ var2 = $ var;

다음을 제거하십시오. 새로운 변수에서 아직 한 번만 발생합니다.

$ var2 = ~ s /.//; # 바꾸세요. 아직 한 번만 비교할 것은 없습니다.

이제 var2는 "."이없는 정수처럼 보입니다. 때문에이 작업을 수행 :

if($var2 !~ /^[+-]?\d+$/){ 
     print "not valid"; 
    }else{ 
     #use var1 
    } 

이 코드를 수정하고 당신이 그것을 한 번 이상 사용해야 할 경우 함수로 쓸 수 있습니다. 건배!

관련 문제