2015-02-04 4 views
1

문자열이 여러 정규식 패턴과 일치하는지 확인하는 더 좋은 방법을 찾고 있습니다. 이 지금까지 나의 접근 방식은 다음과 같습니다Ruby에서 여러 정규식 조건을 확인하는 더 나은 방법은?

class Bob 
    def hey(remark) 
    if remark =~ upcase && !(remark =~ downcase) && !(remark =~ numbers) 
     'Whoa, chill out!' 
    elsif remark =~ ends_with_questionmark 
     'Sure.' 
    elsif (remark =~ numbers) && (remark =~ upcase) && !(remark =~ downcase) 
     'Whoa, chill out!' 
    else 
     'Whatever.' 
    end 
    end 
    def numbers 
    /[\d]+/ 
    end 
    def downcase 
    /[a-z]+/ 
    end 
    def upcase 
    /[A-Z]+/ 
    end 
    def ends_with_questionmark 
    /[\?]$/ 
    end 
end 
+0

이 로직 elsif (remark = ~ numbers) && (remark = ~ upcase) &&! (remark = ~ downcase)는 절대로 적용되지 않습니다. 그리고 방법보다는 상수로 정규식을 정의하는 것이 더 낫다고 생각합니다. –

+0

@ToanNguyen,'remark = 7UP'이라고 가정하십시오. –

+1

이 질문은 Katrina Owen의 "잔인한 (Overkill)"강연에서 리팩터링되었습니다. 그녀가 가독성을 향상시키는 방법을보기에는 꽤 흥미 롭습니다. 리뷰를 작성하면 재미있을 것입니다. 어쩌면 내가 이야기를 듣고 어떻게 해결했는지 살펴볼 수 있습니다. http://exercism.io/submissions/736312a54538483ea43cefdb07592e8d –

답변

3

str !~ /re/

또한 당신은 변경할 수 있습니다. 하나의 가능성은 String 클래스의 일부 적절하게 명명 된 도우미 메서드를 정의하는 것입니다 :

class String 
    def contains_a_digit?()   !!(self =~ /\d/)  end 
    def contains_no_digits?()   !self.contains_a_digit? end 
    def contains_an_uppercase_char?() !!(self =~ /[A-Z]/)  end 
    def contains_no_lowercase_chars?() self !~ /[a-z]/   end 
    def ends_with_questionmark?()  !!(self =~ /[\?]$/)  end 
end 

참고 self =~ /\d+/self =~ /\d/ 여기에 교환 할 수있다 (예를 들어); self에 적어도 하나의 숫자가 포함 된 경우에만 진리 값을 반환합니다. 덧붙여서, 수신기, self은 여기에 분명해야합니다. !!에 익숙하지 않은 독자를 제외하고

: truthyfalse 또는 nil, !!(truthy) => true, !!(nil) => false!!(false) => false 이외의 값을 보관 유지하는 변수가됩니다. 다시 말해서 !!은 진실 값을 true으로, 거짓 값을 false (가독성을 높이기 위해 사용한 것)으로 변환하는 트릭입니다.

은의이 방법을 시도하자 루비 2.1와

str = 'U2d?'      #=> "U2d?" 
str.contains_a_digit?   #=> true 
str.contains_no_digits?   #=> false 
str.contains_an_uppercase_char? #=> true 
str.contains_no_lowercase_chars? #=> false 
str.ends_with_questionmark?  #=> true 

, 하나는 원숭이를 패치 String 클래스를 하나 Refinements을 사용할 수 있습니다에 꺼렸 경우.

는 이제 방법 Bob#hey은 자연적인 방법으로 정의 할 수 있습니다 :

class Bob 
    def hey(remark) 
    case 
    when remark.contains_no_digits? && 
     remark.contains_an_uppercase_char? && 
     remark.contains_no_lowercase_chars? 
     'Whoa, chill out! (1st)' 
    when remark.ends_with_questionmark? 
     'Sure.' 
    when remark.contains_a_digit? && 
     remark.contains_an_uppercase_char? && 
     remark.contains_no_lowercase_chars? 
     'Whoa, chill out! (2nd)' 
    else 
     'Whatever.' 
    end 
    end 
end 

것은 그것을 시도하자.

bob = Bob.new 
bob.hey("I PAID IN $US!") #=> "Whoa, chill out! (1st)" 
bob.hey("What's that?")  #=> "Sure." 
bob.hey("I FLEW ON A 777!") #=> "Whoa, chill out! (2nd)" 
bob.hey("I give up.")  #=> "Whatever." 
0

당신의 코드는 case해야 내가 일반적으로 2 개 이상의 else의 생각이

def hey(remark) 
    if remark =~ /[A-Z]+/ 
     'Whoa, chill out!' 
    elsif remark =~ /[\?]$/ 
     'Sure.' 
    else 
     'Whatever.' 
    end 
    end 
1

처럼 쓸 수있다 :

def hey remark 
    case 
    when remark =~ upcase && !(remark =~ downcase) && !(remark =~ numbers) then 'Whoa, chill out!' 
    when remark =~ ends_with_questionmark then 'Sure.' 
    when (remark =~ numbers) && (remark =~ upcase) && !(remark =~ downcase) then 'Whoa, chill out!' 
    else 'Whatever.' 
    end 
end 

그러나 나는 또한 그 정규 표현식이 일할 필요가 있다고 생각한다. 아마도 당신이 생각하는 것을하지 않을 것이다. 나는 어려운 무엇을하고 있는지 Bob#hey 이해 찾을 !(str =~ /re/)

+0

저는 여러분에게'case statements'을 사용하고 있습니다. 나는'if ... end'를 더 이상 사용하지 않고, elsif가없는 벌거숭이'case '를 만들었을 때도 사용합니다. 나는 단지 '사례 진술'을 읽기 쉽고 심미적으로 더 즐겁게 생각합니다. 내가'if '를 사용하는 유일한 시간은'do something something if ...'입니다. –