Ruby on Rails 응용 프로그램을 사용하고 있습니다. 응용 프로그램에서 하나의 장소에서 나는 API를 호출하는 내게 문자열을 Up 4.35% from Oct to Nov
반환합니다. 내 요구 사항은 내가 이것을 Up 4.35% from October to November
으로 표시해야하는 사용자 인터페이스에 표시 할 때입니다.Ruby에서 문자열에서 월 이름을 추출하십시오.
누군가 어떻게 말해 줄 수 있습니까?
Ruby on Rails 응용 프로그램을 사용하고 있습니다. 응용 프로그램에서 하나의 장소에서 나는 API를 호출하는 내게 문자열을 Up 4.35% from Oct to Nov
반환합니다. 내 요구 사항은 내가 이것을 Up 4.35% from October to November
으로 표시해야하는 사용자 인터페이스에 표시 할 때입니다.Ruby에서 문자열에서 월 이름을 추출하십시오.
누군가 어떻게 말해 줄 수 있습니까?
Date::MONTHNAMES
당신을 도울 수 있습니다.
dates = Date::MONTHNAMES.compact.map { |m| [m[0..2], m] }.to_h
을 그런 다음 다른 곳을 사용합니다 : 그들은 달의 3 문자 단축 버전이 항상 있다면, 당신은 도움이되는 해시를 만들 수
는text = 'Up 4.35% from Oct to Nov'
text.gsub(/#{dates.keys.join('|')}/, dates)
=> "Up 4.35% from October to November"
Date :: MONTHNAMES와 좋은 아이디어가 있지만 더 나은 솔루션을 위해 MikDiet의 대답에 @ toro2k의 의견을 결합합니다. –
사실. 그 (것)들을 사용하기 위하여 새롭게하십시오. –
'dates.keys.join ('|')'에주의하십시오. –
gsub
을 사용할 수 있습니다.
"Up 4.35% from Oct to Nov".gsub(/Oct|Nov/) do |s|
{'Oct' => 'October', 'Nov' => 'November'}[s]
end
# => "Up 4.35% from October to November"
해시를'gsub'의 두 번째 인수로 전달할 수 있습니다. 블록을 사용할 필요가 없습니다. 'abc'.gsub (/ a | b /,'a '=>'x ','b '=> 'y') # => 'xyc''. – toro2k
def replace(string)
string.gsub("Jan", "January").gsub("Feb", "February").gsub("Mar", "March").gsub("Apr", "April").gsub("Jul", "July").gsub("Aug", "August").gsub("Sep", "September").gsub("Oct", "October").gsub("Nov", "November").gsub("Dec", "December")
end
str = "Up 4.35% from Oct to Nov"
을하고 마지막에, 단지 함수를 호출 :
그냥 모든 개월 내 예제를 확장
replace(str)
String#sub
당신이
이 시도해야 할 것입니다 :
a = "Up 4.35% from Oct to Nov"
a.sub('Oct', 'October').sub('Nov', 'November') # you can continue with other months
#=> "Up 4.35% from October to November"
사람들은 gsub
이 특별한 관심을 지불하지 않습니다 능력 때문에,이 묵상 :
SHORT_TO_LONG_MONTH_NAMES = %w[
January
February
March
April
May
June
July
August
September
October
November
December
].map{ |m| [m[0, 3], m] }.to_h
# => {"Jan"=>"January", "Feb"=>"February", "Mar"=>"March", "Apr"=>"April", "May"=>"May", "Jun"=>"June", "Jul"=>"July", "Aug"=>"August", "Sep"=>"September", "Oct"=>"October", "Nov"=>"November", "Dec"=>"December"}
SHORT_TO_LONG_MONTH_NAMES_REGEX = /\b(?:#{ Regexp.union(SHORT_TO_LONG_MONTH_NAMES.keys).source })\b/
# => /\b(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\b/
str = 'Up 4.35% from Oct to Nov'
str.gsub(SHORT_TO_LONG_MONTH_NAMES_REGEX, SHORT_TO_LONG_MONTH_NAMES)
# => "Up 4.35% from October to November"
빠른 검색을 수행하고 문서로 대체하는 매우 간결한 방법으로 출력 결과를 스트리핑 :
SHORT_TO_LONG_MONTH_NAMES = Hash[%w[
January
February
March
April
May
June
July
August
September
October
November
December
].map{ |m| [m[0, 3], m] }]
# => {"Jan"=>"January", "Feb"=>"February", "Mar"=>"March", "Apr"=>"April", "May"=>"May", "Jun"=>"June", "Jul"=>"July", "Aug"=>"August", "Sep"=>"September", "Oct"=>"October", "Nov"=>"November", "Dec"=>"December"}
는 정규식 패턴 생성을 깨는 :
SHORT_TO_LONG_MONTH_NAMES = %w[
January
February
March
April
May
June
July
August
September
October
November
December
].map{ |m| [m[0, 3], m] }.to_h
SHORT_TO_LONG_MONTH_NAMES_REGEX = /\b(?:#{ Regexp.union(SHORT_TO_LONG_MONTH_NAMES.keys).source })\b/
str = 'Up 4.35% from Oct to Nov'
str.gsub(SHORT_TO_LONG_MONTH_NAMES_REGEX, SHORT_TO_LONG_MONTH_NAMES)
# => "Up 4.35% from October to November"
이전 루비가 to_h
그래서 대신이 사용할 수없는
SHORT_TO_LONG_MONTH_NAMES_REGEX = /\b(?:#{ Regexp.union(SHORT_TO_LONG_MONTH_NAMES.keys).source })\b/
\b
단어 휴식 또는 낱말 경계, 낱말이 시작하거나 끝나는 곳 의미. "단어"는 문자 집합 [a-zA-Z0-9_]
, AKA \w
이며 단어 분리는 이전 단어가 아닌 문자와 단어 문자 사이의 구분선입니다. 그렇게하지 않으면 모든 종류의 인간 비참함의 뿌리입니다. 하위 문자열은 \b
없이 일치하므로 모든 종류의 흥미로운 대체물을 얻을 수 있습니다.(?:...)
은 일련의 대체 패턴을 찾는 좋은 방법 인 비 캡처 그룹을 정의합니다.이 경우 3 자의 단축 된 월 이름 목록입니다.Regexp.union
은 배열 (이 경우 해시 키)을 사용하여 패턴의 OR 기호 인 |
으로 구분하는 유용한 방법입니다. 기본적으로 이것은 어떤 키도 일치 할 수 있음을 의미합니다.source
은 매우 중요한 부분입니다.이를 제외하면, 컴파일 된 정규 표현식 인 Regexp.union
의 결과는 충돌하는 검색을 유발할 수있는 관련 플래그와 함께 문자열로 보간됩니다. 다음의 차이점을 고려하십시오.
/foo/i # => /foo/i
/#{ /foo/i }/ # => /(?i-mx:foo)/
/foo/i.source # => "foo"
/#{ /foo/i.source }/ # => /foo/
첫 번째 문자는 대소 문자를 구분하지 않습니다. 두 번째는 대소 문자를 구분하는 패턴이며 대소 문자를 구분하는 패턴입니다. 그러나 (?i-mx:
은 내부적으로 무시합니다. 그것이 당신이 정말로 원하는 것이 확실하지 않다면 그것은 기다리는 중에 벌레입니다.
source
은 플래그없이 패턴의 문자열 버전을 반환하므로 최종 결과는 실제로 기대했던 것입니다.
나는 그 전에 물었다. 그리고 그것은 추적하는 주요한 고통이었다.
마지막으로, Date 클래스에는 미리 정의 된 상수가 있으므로 위와 같이 해시를 정의하지 않아도됩니다. 즉 무슨 일이 일어 났는지는 분명하게했지만, 편의를 위해 당신은 같은 일을 수행 할 수 있습니다
require 'date'
Date::ABBR_MONTHNAMES.zip(Date::MONTHNAMES)[1..-1].to_h # => {"Jan"=>"January", "Feb"=>"February", "Mar"=>"March", "Apr"=>"April", "May"=>"May", "Jun"=>"June", "Jul"=>"July", "Aug"=>"August", "Sep"=>"September", "Oct"=>"October", "Nov"=>"November", "Dec"=>"December"}
Hash[Date::ABBR_MONTHNAMES.zip(Date::MONTHNAMES)[1..-1]] # => {"Jan"=>"January", "Feb"=>"February", "Mar"=>"March", "Apr"=>"April", "May"=>"May", "Jun"=>"June", "Jul"=>"July", "Aug"=>"August", "Sep"=>"September", "Oct"=>"October", "Nov"=>"November", "Dec"=>"December"}
/\b(?:#{ Regexp.union(Date::ABBR_MONTHNAMES[1..-1]).source }\b)/ # => /\b(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec\b)/
공지 사항 샘플에서 [1..-1]
의 사용. 그 이유는 배열에 첫 번째 값을위한 nil이 포함되어 있기 때문입니다. 0을 기준으로하지 않고 배열을 기반으로하여 조회의 즐거움을 얻으려고하지만 배열에 패턴을 사용하려는 경우 Ruby 울부 짖음을 만들 수 있습니다.
문자열 형식은 예제와 같이 항상 월을 포함합니까? –