2012-09-25 4 views
1

간단한 질문 : 스크립트의 사용자에게 임의의 배열을 입력 할 수있는 가능성을 제공하고자합니다. "[1 .. 5]" 또는 "[1, 2, 6, 9 .. 20]"입니다. 현재, 나는 단지 eval 주어진 문자열 (분명히 매우 안전하지 않다!)과 perlcritic은 나에게 레벨 5 경고를 준다.userinput에서 배열 가져 오기

내 현재 코드 :

my $arr = eval $patternData{"arr"}; 
unless ($arr) { 
    # fixes <arr> values like "(1 .. 5)" 
    $arr = undef; 
    @$arr = eval $patternData{"arr"}; 
} 

편집 : 많은 사람들이 물어 :이 "더 - 더 - 더 - 더 나은"꼬입니다. 나는 강력 함 (표현의 측면에서)과 간단한 (디버깅, 파싱 및 입력 작성의 관점에서) 모두 해결책을 찾는다. 또한 : 그것은 절대적으로 범위를 지원해야합니다 (100 개가 넘는 배열은 쉽게 입력되어야합니다)

- 항상 - 내 버전을 포함하는 것을 잊었습니다. 5.8 내가 5.8이 필요의 vSphere API, 함께 일하고 있어요, 필수입니다 (I 너무 ~~를 그리워!)

This is perl, v5.8.8 built for MSWin32-x86-multi-thread 
(with 50 registered patches, see perl -V for more detail) 

Copyright 1987-2006, Larry Wall 

Binary build 820 [274739] provided by ActiveState http://www.ActiveState.com 
Built Jan 23 2007 15:57:46 
+0

임의의 배열에는'[map {($ _, $ _ + 7)} split //, q (123)]'또는 실제로 얼마나 표현력이 필요한가요? – pmakholm

+0

[이 도움이되는지 확인하십시오.] (http://search.cpan.org/~tlinden/Data-Validate-Struct-0.06/Struct.pm) – tuxuday

답변

4

현재 입력 형식은 어떤 관계입니까?

하나의 목표는 형식을 JSON으로 "변경"하고 JSON :: XS를 사용하여 입력을 비 직렬화 할 수 있습니다. [1, 2, 3, 4]은 유효한 입력이지만 여전히 허용되지 않습니다. [1, 2, 3, 4, 8 .. 10 ]

모든 경우에 입력 데이터의 구조가 올바른지 확인해야합니다.

+1

또 다른 대안은 [Parse :: Range] (http://search.cpan.org/perldoc?Parse%3A%3ARange)를 사용하는 것입니다. 이렇게하면 범위가 지정되지만 정수 목록 만 지원합니다. (플러스 일 수 있습니다). – pmakholm

+0

Parse :: Range는 꽤 괜찮은 것처럼 보입니다. 코드가 더 큰지 (프로젝트가 더 큰 프로젝트의 일부이고 요구 사항이 프로젝트와 함께 발전했는지는 잘 모르겠다)) 그러나 적어도 중기 솔루션으로 작동합니다. 편집 : 분석 : : 범위는 ppm으로 포함되어 있지 않습니다 : / – incaseoftrouble

2

배열은 숫자 만 허용하는 경우, 나는 구문 분석하기 쉬운 것 (이 패턴을 선택하는 것) :

[1, 2, 3, 4] 

또한 중첩 된 배열이 없다고 가정합니다. [1, [2, 3]] 또는 후행 쉼표 [1,]

그렇다면 우리는 단지 배열

my $line = <STDIN>; 
$line =~ s/ ^\s*\[ | \]\s*$ //gx; 

을 구분 기호와 펄 배열로 배열 분할 스트립. 두 번째 솔루션은 엄격한 (그리고 아마도 안전) 인 반면 우리는 또한 문자열을 포함 예를 들어 [1, two, 3]을 허용 할 split

my @array = split /,\s*/, $line; 

를 통해 또는 모든 숫자

my @array = ($line =~ /(\d+)(?:,\s*|$)/g); 

에게 split 솔루션을 추출을 통해이 작업을 수행 할 수 있습니다 .

두 번째 단계에서는 범위를 구문 분석 할 수 있습니다. (인용 재귀)

@array = map { 
    ($_ =~ /^(-?[\d.]+)\s*\.\.\s*(-?[\d.]+)/) 
    ? ($1 .. $2) 
    : $_ 
} @array; 

데이터 구조가 더 복잡 얻을 경우

을 통해, 내가보기 엔 Regexp::Grammars으로 파서를 작성 보시기 바랍니다. 이렇게하면 재귀 구조 및 기타 거의 모든 것을 쉽게 구문 분석 할 수 있습니다.

+0

"정규식"에 대해서도 생각했지만 다소 복잡 할 것입니다. 형식이 복잡해지면 디버그하십시오. 이 문법 모듈을 확실히 살펴 보겠습니다! – incaseoftrouble