2011-11-23 2 views
0

과 일치하도록 수정하십시오. 순차적으로 YYYY-YY과 일치시키고 싶습니다.참조 번호가 매겨진 그룹을

나는 YYYY에 1이 추가 된 두 번째 문자 인 YY이 3 번째와 4 번째 문자 모두 일치하도록하려고합니다.

지금까지 내가 {19|20}(\d{2})-(\d{2})를 가지고 있지만이 방법으로 (1) 또는 (YY99 같은) 내가 피할 수없는 "알 수없는 미지수"을 찾는 이것에 대해 올바른 길을 가고있어 여부를 참조하여 ?를 사용하는 방법을 잘 ?

편집 :

일치 : 1999-00, 2010-11, 2011-12, 2029-30
가 일치하지 않습니다 2010-12, 2010-09, 2011-2, 2011-2012

+0

무엇을 몇 가지 더 예를 제공하십시오 당신은 일치하려고하고 무엇이 가까울 지 모르지만 일치하지 않아야합니다. –

+0

OK, 질문을 이해할 수 있다고 생각합니다. 그러나 많은 언어에는 정규 표현식에서 다른 제한과 구문이 있습니다. 사용하는 언어는 무엇입니까? Java, PHP .Net, JavaScript? –

+1

'1999-00'은 어떨까요 (예 :'1999-2000')? – NullUserException

답변

2

2 가지 방법이 있습니다 :

  1. 하드 방법은 역 참조를 사용하는 것입니다. 검사 할 소수점 당 10 개의 캡쳐 버퍼가 필요합니다. 따라서이 경우에는 20 명이 필요합니다. 고급 regex 엔진에서 엔진 내부에서 재귀 및/또는 코드 실행 (평가)을 수행하는 다른 방법이있을 수 있습니다.

  2. 쉬운 방법은 숫자를 캡처하고 처리 만하는 것입니다.

난 당신이 너무 아래에 사용하는 엔진이 두 가지 방법을 보여 예제로 사용하는 펄의 샘플 인 모르겠어요.

@samples = qw(1999-10 1999-00 2010-11 2011-12 2029-30 2010-12 2010-09 2011-2 2011-2012); 

$regex_hard = qr{ 
^
    (?:19|20) 
    (?:1()|2()|3()|4()|5()|6()|7()|8()|9()|0()) 
    (?:1()|2()|3()|4()|5()|6()|7()|8()|9()|0()) 
    - 
    (?: \19(?:\1(?:2)|\2(?:3)|\3(?:4)|\4(?:5)|\5(?:6)|\6(?:7)|\7(?:8)|\8(?:9)|\9(?:0)|\10(?:1)) 
    | (?!\19)\d 
    ) 
    (?:\11(?:2)|\12(?:3)|\13(?:4)|\14(?:5)|\15(?:6)|\16(?:7)|\17(?:8)|\18(?:9)|\19(?:0)|\20(?:1)) 
    $ 
}x; 

for $date (@samples) { 
    print "$date"; 
    if ($date =~ /$regex_hard/) { 
     print " ~ matched $&"; 
    } 
    print "\n"; 
} 

print "\n----------\n"; 


$regex_easy = qr{^(?:19|20) (\d\d) - (\d\d) $ }x; 

print "\n"; 
for $date (@samples) { 
    print "$date"; 
    if ($date =~ /$regex_easy/ && $2 == ($1 == 99 ? 0 : $1+1)) { 
     print " ~ matched $&"; 
    } 
} 

출력 :

1999-10 
1999-00 ~ matched 1999-00 
2010-11 ~ matched 2010-11 
2011-12 ~ matched 2011-12 
2029-30 ~ matched 2029-30 
2010-12 
2010-09 
2011-2 
2011-2012 

---------- 
1999-10 
1999-00 ~ matched 1999-00 
2010-11 ~ matched 2010-11 
2011-12 ~ matched 2011-12 
2029-30 ~ matched 2029-30 
2010-12 
2010-09 
2011-2 
2011-2012 
+0

사용 중입니다. 자바 스크립트, 그래서''후 처리 (post processing) ''와 같은 함수를 작성하면 두 번째 YY에서 첫 번째 YY = 1을 뺀 값을 확인하거나 연속적인 연도를 확인하는 다른 논리를 확인합니다. – StuperUser

+1

가능하지만 바람직하지 않음을 보여주기 위해 허용됩니다. – StuperUser

+0

@SuperUser - 네, 후 처리 로직이 상당히 쉽습니다. Perl에서는 변수의 이중 특성 때문에 $ 1 = $ ($ date = ~/$ regex_easy/&& $ 2 == ($ 1 == 99? 0 : $ 1 + 1)) {// passed}' – sln

1

당신이 물어 내가 생각 요구하는 경우

연도의 범위는 YYYY-YY입니다. 두 자리 연도가 정확히 4 자리 연도 이후 1 년이어야합니까? 예를 들어 1991-92 또는 2010-11과 일치하고 싶지만 1990-98은 아니며 확실히 2009-03이 아닙니다.

그렇다면 정규식으로는 불가능하다고 생각합니다. (확실하게 알려진 언어 나 도구는 아닙니다.) 당신이 그것에 올 수있는 가장 가까운이 같은 것을 사용하는 것입니다 : 다음 중 하나를 수동으로 ...

(19|20)(\d\d)-(\d\d) 

을, 또는 코드로, 두 번째와 세 번째 캡처 그룹은 1의 값의 차이 전에이 있는지 확인 저장, 교체 또는 달리 경기에 대한 행동.

는 편집 : 귀하의 의견을 참조에서 , 나는 무력 (1972-73|1973-74|1974-75...)를 수행하거나 수치 관계를 확인하기 위해 잠재적 인 경기 후 검사를 수행하는 빠른 지 여부를 확신하지 않습니다 - 둘 다 특히 효율적인 것 , 하나는 약간 더 나은 (더 유연함) 만족 스럽습니다 : 사후 일치를 확인하는 알고리즘. 효율에 대한 대답은 아마 당신이 얼마나 오랫동안 지원하길 원하는가에 달려 있습니다.

내가이 일에 착수하기 전에 관련없는 여러 가지 작업을 수행하는 데 약간 시간이 걸릴 수 있지만 다시 확인하면 다른 사람이 나보다 많은 시간을 갖거나 곧 나올 것입니다. (지금은 정말 어떻게라도 code golf type of thing 더 - 당신이 시도 할 수 있습니다)

+0

예, 정확한 질문입니다. '(1990-91 | 1991-92 | ... ad nauseum ... | 2099-00)'로 무차별 대입하는 것이 가능하지만'YYYY '와'YY'? – StuperUser

+0

@StuperUser 표준 정규식 엔진과 함께 사용하는 것은 아닙니다. 아니요. 특수 엔진 (실제 자연이 아닌 일반 엔진)이나 _potential_ 일치 항목을 평가하는 절차 코드가 필요합니다. –

+0

@ CodeJockey 여기에 현혹되는 것에 대해 유감스럽게 생각합니다. 그러나 현대의 정규식 엔진은 실제로 정기적이지 않습니다. – NullUserException

0

당신이 다음이 수행 할 수 있습니다 AWK를 사용할 수있는 경우 -

당신이 ,로 구분 년을 가진 파일을 말해봐.

SED와
[jaypal~/Temp]$ cat years 
1999-00,2010-11,2011-12,2029-30,2010-12,2010-09,2011-2,2011-2012 

, 당신은 파일을 가질 수 있습니다 -

[jaypal~/Temp]$ sed 's/,/\n/g' years 
1999-00 
2010-11 
2011-12 
2029-30 
2010-12 
2010-09 
2011-2 
2011-2012 

이 출력은 찾는 년 연속 AWK로 파이프 할 수 있습니다 -

[jaypal~/Temp]$ sed 's/,/\n/g' years | 
awk -F"-" '{a=substr($1,3,2); a=a+1; if (a==$2) print; else if (length(a)>2 && substr(a,2,2)==$2) print}' 
1999-00 
2010-11 
2011-12 
2029-30 
관련 문제