정규식 및 역 참조로 Ruby switch 문 (case… when)을 작성하는 방법은 무엇입니까?


89

정규식과 일치하는지 확인하기 위해 Ruby case 문을 작성할 수 있다는 것을 알고 있습니다. 그러나 내 return 문에서 일치 데이터를 사용하고 싶습니다. 이 반 의사 코드와 같은 것 :

foo = "10/10/2011"

case foo
    when /^([0-9][0-9])/
        print "the month is #{match[1]}"
    else
        print "something else"
end

어떻게 할 수 있습니까?

감사!


참고 사항 : 위와 같이 간단한 경우에 switch 문을 사용하지 않을 것임을 이해합니다. 그러나 이는 하나의 예일뿐입니다. 실제로 내가 달성하려는 것은 다양한 방식으로 작성할 수있는 날짜에 대해 많은 잠재적 정규식을 일치시킨 다음 그에 따라 Ruby의 Date 클래스로 구문 분석하는 것입니다.


1
Ruby의 Date.parse는 다양한 날짜 형식을 이해합니다. 시도해 보셨습니까?
레인

그것은이 질문에 대답하지 않지만, 당신은 ... 만성 보석을보고 할 수 있습니다
DGM

답변:


156

최신 정규식 일치 그룹에 대한 참조는 항상 다음에 대한 의사 변수 $1 에 저장 됩니다 $9.

case foo
when /^([0-9][0-9])/
    print "the month is #{$1}"
else
    print "something else"
end

$LAST_MATCH_INFO가상 변수를 사용 하여 전체 MatchData개체 를 가져올 수도 있습니다 . 이것은 명명 된 캡처를 사용할 때 유용 할 수 있습니다.

case foo
when /^(?<number>[0-9][0-9])/
    print "the month is #{$LAST_MATCH_INFO['number']}"
else
    print "something else"
end

1
@Yossi 스레드 안전성에 대한 의견의 출처가 있습니까? 방금 루비 1.8.7에서 스레드로부터 안전한 것으로 보이는 실험을했습니다! (1 초마다 정규식과 일치하는 스레드-로컬 일치가 방해받는 경우 irb 확인)
Joel

5
-1 정규 표현식과 관련된 $ 변수는 앞에 달러 기호가 있어도 전역 적이 지 않습니다.
Andrew Grimm 2011

@AndrewGrimm 이것을 지적 해 주셔서 감사합니다. 나는 그것을 몰랐다. 이전 코드를 많이 변경해야합니다.-/
Yossi

당신은 또한 할 수있다 $1, $2... $9또는 Regexp.last_match(1)rubocop 권장
에드가 오르테가을

6

다음은 동일한 결과를 얻지 만 스위치를 사용하지 않는 대체 접근 방식입니다. 정규식을 배열에 넣으면 다음과 같이 할 수 있습니다.

res = [ /pat1/, /pat2/, ... ]
m   = nil
res.find { |re| m = foo.match(re) }
# Do what you will with `m` now.

선언 m블록 외부하면 계속 사용할 이후가 될 수 있도록 find블록으로 수행되며 find스위치가 당신을 제공한다는 동일한 바로 가기 지정 동작을 얻을 수 있도록 블록이 true 값을 반환하는 즉시 중지됩니다. MatchData필요한 경우 전체를 제공 하고 (정규식에서 명명 된 캡처 그룹을 사용하려는 경우) 검색 논리에서 정규식을 멋지게 분리합니다 (더 명확한 코드를 생성하거나 생성하지 않을 수 있음). config 파일을 선택하거나 런타임에 원하는 세트를 선택하십시오.


또한 case접근 방식을 사용하여 스레드 안전성에 대해 생각하고있었습니다 . 경우에 따라 전역 변수가 아닌 스레드 시나리오에서 mu의 접근 방식을 사용하고 싶을 수도 있습니다 (?)
Casper
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.