나는 루비에서 정규 표현식으로 할 수 있는 다른 멋진 트릭을 보고 정규 표현식 조건에 대한 어제 기사를 따라가는 것이 재미있을 것이라고 생각했습니다.
정규 표현식을 통한 문자열 분할
텍스트 구분 기호를 사용하여 문자열을 분할하는 방법은 매우 익숙할 것입니다.
"one,two".split(",")
# => ["one", "two"]
그러나 split도 정규식을 허용한다는 것을 알고 계셨습니까?
# use `,` and `-` as delimiters
"one,two-three".split(/,|-/)
=> ["one", "two", "three"]
# Use comma as thousands separator for US currency,
# but use a space for Euros
"1,000USD".split /(?=.*(USD))(?(1),| )/
구분자 캡처
여기에 깔끔한 파티 트릭이 있습니다. 일반적으로 문자열을 분할하면 구분 기호가 사라집니다.
# The commas vanish!
"one,two".split(",")
# => ["one", "two"]
그러나 정규식을 사용하고 구분 기호를 그룹 안에 넣으면 split
구분 기호도 캡처합니다.
"one,two-three".split(/(,|-)/)
=> ["one", ",", "two", "-", "three"]
이것이 발생하는 이유는 split
실제로 각 캡처 그룹의 경계에서 문자열을 분할합니다.
악용 split
split
을 남용할 수 있습니다. 거의 match
처럼 작동하도록 . 아래 코드에서는 정규식에 4개의 그룹을 사용하여 문자열을 4개로 분할합니다.
"1-800-555-1212".split(/(1)-(\d{3})-(\d{3})-(\d{4})/)
=> ["", "1", "800", "555", "1212"]
정규식은 전체 소스 문자열과 일치하므로 결과 배열의 첫 번째 항목은 빈 문자열입니다.
글로벌 매칭
기본적으로 정규식은 패턴과 한 번만 일치합니다. 아래 코드에서는 5개의 가능한 일치 항목이 있음에도 불구하고 하나의 일치 항목만 얻습니다.
"12345".match /\d/
=> #<MatchData "1">
Perl과 같은 다른 언어에서 해결책은 정규 표현식을 "전역"으로 표시하는 것입니다. Ruby에는 해당 옵션이 없지만 String#scan
이 있습니다. 방법.
scan
메서드는 모든 일치 항목을 포함하는 배열을 반환합니다.
"12345".scan /\d/
=> ["1", "2", "3", "4", "5"]
편리한 블록 구문도 있습니다.
"12345".scan /\d/ do |i|
puts i
end
불행히도 문자열을 느리게 스캔하는 방법은 없는 것 같습니다. 따라서 이 기술은 500MB 파일을 처리하는 데 적합하지 않을 수 있습니다.
그룹으로 스캔
이제 이 시점에서 스캔에서 그룹을 사용하여 어떤 종류의 이상한 트릭을 할 수 있는지 궁금하기를 바랍니다.
불행히도 여기에서의 행동은 완전히 예측 가능하고 지루합니다. 그룹 결과 다차원 배열:
"hiho hiho".scan /(hi)(ho)/
=> [["hi", "ho"], ["hi", "ho"]]
이상한 경우가 하나 있습니다. 그룹을 사용하는 경우 그룹에 없는 항목은 반환되지 않습니다.
"hiho hiho".scan /(hi)ho/
=> [["hi"], ["hi"]]
속기
=~
에 대해 알고 계실 것입니다. 정규식이 문자열과 일치하는지 여부를 확인하는 방법입니다. 일치가 시작되는 문자의 인덱스를 반환합니다.
"hiho" =~ /hi/
# 0
"hiho" =~ /ho/
# 2
하지만 경기를 확인하는 또 다른 빠른 방법이 있습니다. ===
에 대해 이야기하고 있습니다. 운영자.
/hi/ === "hiho"
# true
a === b
를 작성할 때 루비에서는 "b가 다음에 의해 정의된 집합에 속합니까?"라고 묻고 있습니다. 또는 이 경우 "'hiho'는 정규식 /hi/
과 일치하는 문자열 집합에 속합니까? ".
===
연산자는 Ruby의 case 문에서 내부적으로 사용됩니다. 즉, case 문에서도 정규식을 사용할 수 있습니다.
case "hiho"
when /hi/
puts "match"
end
삼중 등호 연산자는 고유한 메서드가 정규식이나 문자열을 허용하도록 하는 데에도 유용할 수 있습니다.
무시할 미리 구성된 클래스 목록에 없는 경우를 제외하고 오류가 발생할 때 일부 코드를 실행하고 싶다고 상상해 보십시오. 아래 예에서는 ===
를 사용합니다. 연산자를 사용하여 사용자가 문자열 또는 정규식을 지정할 수 있습니다.
def ignored?(error)
@ignored_patterns.any? { |x| x === error.class.name }
end
바로 그것입니다!
확실히 Ruby와 Rails에는 이와 같은 수십 가지의 작은 트릭이 흩어져 있습니다. 특히 마음에 드는 것이 있으면 알려주세요!