오픈 소스 모험: 에피소드 79: Crystal Regular Expression API 탐색
많은 솔루션이 Ruby에서와 동일하게 작동하지만 일부 차이점은 흥미롭습니다.
테스트 케이스
Crystal에는
%W
, which is one of my favorite Ruby features 이 없지만 이 경우 비보간 및 훨씬 덜 멋진 상대%w
가 수행됩니다.테스트 사례는 다음과 같습니다.
%w[
2015-05-25
2016/06/26
27/07/2017
].each do |s|
p parse_date(s)
end
그리고 예상 결과:
[2015, 5, 25]
[2016, 6, 26]
[2017, 7, 27]
솔루션 1
def parse_date(s)
case s
when %r[(\d\d\d\d)-(\d\d)-(\d\d)]
[$1.to_i, $2.to_i, $3.to_i]
when %r[(\d\d\d\d)/(\d\d)/(\d\d)]
[$1.to_i, $2.to_i, $3.to_i]
when %r[(\d\d)/(\d\d)/(\d\d\d\d)]
[$3.to_i, $2.to_i, $1.to_i]
end
end
가장 간단한 솔루션은 변경 없이 Ruby에서와 동일하게 작동합니다.
솔루션 2
#!/usr/bin/env crystal
def parse_date(s)
case s
when %r[(\d\d\d\d)-(\d\d)-(\d\d)], %r[(\d\d\d\d)/(\d\d)/(\d\d)]
[$1.to_i, $2.to_i, $3.to_i]
when %r[(\d\d)/(\d\d)/(\d\d\d\d)]
[$3.to_i, $2.to_i, $1.to_i]
end
end
그룹화
when
옵션은 Ruby에서와 동일하게 작동합니다.해결책 3
def parse_date(s)
case s
when %r[(\d\d\d\d)([/-])(\d\d)\2(\d\d)]
[$1.to_i, $3.to_i, $4.to_i]
when %r[(\d\d)/(\d\d)/(\d\d\d\d)]
[$3.to_i, $2.to_i, $1.to_i]
end
end
역참조도 Ruby에서처럼 작동합니다.
해결책 4
이제 이것은 작동하지 않습니다.
def parse_date(s)
case s
when %r[(\d\d\d\d)-(\d\d)-(\d\d)|(\d\d\d\d)/(\d\d)/(\d\d)]
[($1 || $4).to_i, ($2 || $5).to_i, ($3 || $6).to_i]
when %r[(\d\d)/(\d\d)/(\d\d\d\d)]
[$3.to_i, $2.to_i, $1.to_i]
end
end
그 이유는 Ruby에서
$1
는 String
또는 nil
일 수 있기 때문입니다. Crystal$1
에서는 String
이므로 일치하지 않으면 액세스하는 오류입니다.Crystal은 또한
nil
가능한 등가물 $1?
, $2?
등을 가지고 있습니다.def parse_date(s)
case s
when %r[(\d\d\d\d)-(\d\d)-(\d\d)|(\d\d\d\d)/(\d\d)/(\d\d)]
[($1? || $4).to_i, ($2? || $5).to_i, ($3? || $6).to_i]
when %r[(\d\d)/(\d\d)/(\d\d\d\d)]
[$3.to_i, $2.to_i, $1.to_i]
end
end
솔루션 5
def parse_date(s)
case s
when %r[(\d\d\d\d)-(\d\d)-(\d\d)|(\d\d\d\d)/(\d\d)/(\d\d)|(\d\d)/(\d\d)/(\d\d\d\d)]
[($1? || $4? || $9).to_i, ($2? || $5? || $8).to_i, ($3? || $6? || $7).to_i]
end
end
우리가 아는 것을 알면 동일한 트릭을 사용하여
?
를 ($1 || $4 || $9)
로 다시 작성할 수 있습니다.해결책 6
def parse_date(s)
case s
when
%r[(?<year>\d\d\d\d)-(?<month>\d\d)-(?<day>\d\d)],
%r[(?<year>\d\d\d\d)/(?<month>\d\d)/(?<day>\d\d)],
%r[(?<day>\d\d)/(?<month>\d\d)/(?<year>\d\d\d\d)]
[$~["year"].to_i, $~["month"].to_i, $~["day"].to_i]
end
end
명명된 캡처 사용은 Ruby 버전과 동일하게 작동합니다.
해결책 7
def parse_date(s)
case s
when %r[(?<year>\d\d\d\d)-(?<month>\d\d)-(?<day>\d\d)|(?<year>\d\d\d\d)/(?<month>\d\d)/(?<day>\d\d)|(?<day>\d\d)/(?<month>\d\d)/(?<year>\d\d\d\d)]
[$~["year"].to_i, $~["month"].to_i, $~["day"].to_i]
end
end
동일한 이름의 캡처 그룹을 갖는 것은 변경 없이 Ruby에서와 동일하게 작동합니다.
해결책 8
def parse_date(s)
case s
when %r[
(?<year>\d\d\d\d)-(?<month>\d\d)-(?<day>\d\d) |
(?<year>\d\d\d\d)/(?<month>\d\d)/(?<day>\d\d) |
(?<day>\d\d)/(?<month>\d\d)/(?<year>\d\d\d\d)
]x
[$~["year"].to_i, $~["month"].to_i, $~["day"].to_i]
end
end
($1? || $4? || $9)
플래그도 마찬가지입니다. 모든 것이 제대로 작동합니다.해결책 9
def parse_date(s)
if %r[
(?<year>\d\d\d\d)-(?<month>\d\d)-(?<day>\d\d) |
(?<year>\d\d\d\d)/(?<month>\d\d)/(?<day>\d\d) |
(?<day>\d\d)/(?<month>\d\d)/(?<year>\d\d\d\d)
]x =~ s
[year.to_i, month.to_i, day.to_i]
end
end
반면에 이것은 완전히 지원되지 않습니다. 정규식 일치의 유일한 부작용은
//x
변수를 재정의하는 것입니다($~
는 $1
등의 별칭입니다). 정규식 일치는 다른 지역 변수를 재정의할 수 없습니다.저는 이 Ruby 기능이 그다지 편하지 않기 때문에 여기에서 해당 기능을 찾지 못한 것은 놀라운 일이 아닙니다.
지금까지의 이야기
모든 것이 전혀 또는 최소한의 변경으로 작동했습니다. 이것은 Crystal에 대한 나의 일반적인 경험입니다. 모든 것이 대부분의 시간에 작동합니다.
All the code is on GitHub .
다음에 온다
다음 에피소드에서는 다른 언어가 이 문제를 어떻게 처리하는지 살펴보겠습니다.
Reference
이 문제에 관하여(오픈 소스 모험: 에피소드 79: Crystal Regular Expression API 탐색), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/taw/open-source-adventures-episode-79-exploring-crystal-regular-expression-api-cnj텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)