Ruby 정규식(ruby regex 줄여서) 추가 처리를 위해 데이터를 추출할 목적으로 문자열 내부의 특정 패턴을 찾는 데 도움이 됩니다.
정규 표현식의 두 가지 일반적인 사용 사례에는 유효성 검사 및 구문 분석이 있습니다.
예를 들어 :
ruby regex가 있는 이메일 주소를 생각해 보세요. 유효한 이메일 주소의 모양을 정의할 수 있습니다. 즉, 귀하의 프로그램은 유효한 이메일 주소와 유효하지 않은 이메일 주소를 구별할 수 있습니다.
루비 정규식은 두 개의 슬래시 사이에 정의됩니다. 다른 언어 구문과 구별하기 위해. 가장 단순한 표현은 단어 또는 한 글자와도 일치합니다.
예를 들어 :
# Find the word 'like' "Do you like cats?" =~ /like/
이것은 단어가 발견된 경우(성공한 일치) 또는 nil
인 경우 단어가 처음 나타나는 인덱스를 반환합니다. 그렇지 않으면. 인덱스에 신경 쓰지 않는다면 String#include? 방법.
문자열이 정규식과 일치하는지 확인하는 또 다른 방법은 match
를 사용하는 것입니다. 방법:
if "Do you like cats?".match(/like/) puts "Match found!" end
지금:
날짜, 전화번호, 이메일, URL 등과 같은 항목을 일치, 캡처 및 대체할 수 있도록 보다 고급 패턴을 구축하는 방법을 배우게 됩니다.
캐릭터 클래스
문자 클래스를 사용하면 일치시킬 문자 범위 또는 목록을 정의할 수 있습니다. 예:[aeiou]
모든 모음과 일치합니다.
예 :문자열이 포함합니까? 모음?
def contains_vowel(str) str =~ /[aeiou]/ end contains_vowel("test") # returns 1 contains_vowel("sky") # returns nil
금액은 고려되지 않습니다. 그 방법을 곧 알게 될 것입니다.
범위
범위를 사용하여 모두 입력하지 않고도 여러 문자나 숫자를 일치시킬 수 있습니다. 즉, [2-5]
와 같은 범위 [2345]
와 동일합니다. .
몇 가지 유용한 범위:
- [0-9] 0에서 9까지의 숫자와 일치
- [a-z] a에서 z까지의 모든 문자와 일치(대문자 없음)
- [^a-z] 부정 범위
예 :이 문자열에 숫자가 포함되어 있습니까?
def contains_number(str) str =~ /[0-9]/ end contains_number("The year is 2015") # returns 12 contains_number("The cat is black") # returns nil<블록 인용>
기억하세요:`=~`를 사용할 때 반환 값은 문자열 인덱스 또는 `nil`입니다.
문자 범위를 지정하기 위한 좋은 약식 구문이 있습니다.
- \w [0-9a-zA-Z_]와 동일합니다.
- \d [0-9]과(와) 동일합니다.
- \s 공백과 일치 (탭, 일반 공백, 줄 바꿈)
다음과 같은 부정적인 형태도 있습니다.
- \W [0-9a-zA-Z_]에 없는 모든 것
- \D 숫자가 아닌 모든 것
- \S 공백이 아닌 모든 것
점 문자 .
새 줄을 제외한 모든 것과 일치합니다. 리터럴 .
를 사용해야 하는 경우 그러면 탈출해야 합니다.
예 :특수 문자 이스케이프
# If we don't escape, the letter will match "5a5".match(/\d.\d/) # In this case only the literal dot matches "5a5".match(/\d\.\d/) # nil "5.5".match(/\d\.\d/) # match
수정자
지금까지는 한 번에 하나의 문자만 일치시킬 수 있었습니다. 여러 문자를 일치시키기 위해 패턴 수정자를 사용할 수 있습니다.
수정자 | 설명 |
---|---|
+ | 1개 이상 |
* | 0 이상 |
? | 0 또는 1 |
{3,5} | 3에서 5 사이 |
지금까지 배운 모든 것을 결합하여 더 복잡한 정규 표현식을 만들 수 있습니다.
예 :IP 주소처럼 보이나요?
# Note that this will also match some invalid IP address # like 999.999.999.999, but in this case we just care about the format. def ip_address?(str) # We use !! to convert the return value to a boolean !!(str =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) end ip_address?("192.168.1.1") # returns true ip_address?("0000.0000") # returns false
정확한 문자열 일치
정확한 일치가 필요한 경우 다른 유형의 수정자가 필요합니다. 제가 무슨 말을 하는지 알 수 있도록 예를 들어보겠습니다.
# We want to find if this string is exactly four letters long, this will # still match because it has more than four, but it's not what we want. "Regex are cool".match /\w{4}/ # Instead we will use the 'beginning of line' and 'end of line' modifiers "Regex are cool".match /^\w{4}$/ # This time it won't match. This is a rather contrived example, since we could just # have used .size to find the length, but I think it gets the idea across.
모든 라인이 아니라 문자열의 시작 부분에서 엄격하게 일치하려면(\n
뒤) ) \A
를 사용해야 합니다. 및 \Z
^
대신 및 $
.
캡처 그룹
캡처 그룹을 사용하면 일치 항목의 일부를 캡처하고 나중에 다시 사용할 수 있습니다. 매치를 캡처하기 위해 캡처하려는 부분을 괄호로 묶습니다.
예 :로그 파일 파싱
Line = Struct.new(:time, :type, :msg) LOG_FORMAT = /(\d{2}:\d{2}) (\w+) (.*)/ def parse_line(line) line.match(LOG_FORMAT) { |m| Line.new(*m.captures) } end parse_line("12:41 INFO User has logged in.") # This produces objects like this: #
이 예에서는 .match
를 사용하고 있습니다. =~
대신 .
이 메서드는 MatchData
를 반환합니다. 일치하는 항목이 있으면 개체, 그렇지 않으면 nil입니다. MatchData
클래스에는 유용한 방법이 많이 있습니다. 자세한 내용은 설명서를 확인하세요!
부울 값만 원하는 경우(true
/ false
) 그런 다음 match?
를 사용할 수 있습니다. Ruby 2.4부터 사용할 수 있는 메서드입니다. 이것은 match
보다 빠릅니다. Ruby는 MatchData
를 생성할 필요가 없기 때문에 개체.
.captures
를 사용하여 캡처된 데이터에 액세스할 수 있습니다. 메소드 또는 MatchData
처리 배열과 같은 개체의 경우 0 인덱스에는 전체 일치 항목이 포함되고 결과 인덱스에는 일치하는 그룹이 포함됩니다.
첫 번째 캡처 그룹을 원하는 경우 다음을 수행할 수 있습니다.
m = "John 31".match /\w+ (\d+)/ m[1] # 31
캡처하지 않는 그룹을 가질 수도 있습니다. 성능 저하 없이 표현식을 그룹화할 수 있습니다. 복잡한 표현식을 읽기 쉽게 만드는 데 유용한 명명된 그룹을 찾을 수도 있습니다.
구문 | 설명 |
---|---|
(?:...) | 비 캡처 그룹 |
(?<foo>...) | 명명된 그룹 |
예 :명명된 그룹
m = "David 30".match /(?\w+) (?\d+)/ m[:age] # => "30" m[:name] # => "David"
명명된 그룹은 MatchData
를 반환합니다. 결과를 읽기 위해 액세스할 수 있는 개체입니다.
앞을 내다보고 뒤를 돌아보세요
이것은 모든 정규식 구현에서 사용할 수 없는 고급 기술입니다. Ruby의 정규식 엔진은 이를 수행할 수 있으므로 이를 활용하는 방법을 살펴보겠습니다.
미리보기를 통해 특정 경기가 전후에 있는지 살짝 살펴보겠습니다.
이름 | 설명 |
---|---|
(?=pat) | 긍정적인 전망 |
(?<=pat) | 긍정적인 비하인드 |
(?!pat) | 부정적 예측 |
(? | 네거티브 룩비하인드 |
예 :적어도 하나의 문자가 앞에 오는 숫자가 있습니까?
def number_after_word?(str) !!(str =~ /(?<=\w) (\d+)/) end number_after_word?("Grade 99")
Ruby의 정규식 클래스
Ruby 정규식은 Regexp
의 인스턴스입니다. 수업. 대부분의 경우 이 클래스를 직접 사용하지는 않지만 알아두면 좋습니다. 🙂
puts /a/.class # Regexp
한 가지 가능한 사용은 문자열에서 정규식을 만드는 것입니다.
regexp = Regexp.new("a")
정규 표현식을 만드는 또 다른 방법:
regexp = %r{\w+}
정규식 옵션
정규 표현식에 몇 가지 옵션을 설정하여 다르게 작동하도록 할 수 있습니다.
옵션 | 설명 |
---|---|
나 | 루비 정규식 대소문자를 구분하지 않음 |
m | 점은 개행과 일치 |
x | 공백 무시 |
이 옵션을 사용하려면 /
를 닫은 후 정규식 끝에 문자를 추가합니다. .
좋아요 :
"abc".match?(/[A-Z]/i)
긴 정규 표현식 서식 지정
복잡한 Ruby 정규식은 읽기 어려울 수 있으므로 여러 줄로 나누면 도움이 됩니다. 'x' 수식어를 사용하여 이를 수행할 수 있습니다. 이 형식을 사용하면 정규식 내에서 주석을 사용할 수도 있습니다.
예 :
LOG_FORMAT = %r{ (\d{2}:\d{2}) # Time \s(\w+) # Event type \s(.*) # Message }x
Ruby 정규식:모두 합치기
정규식은 다양한 Ruby 메서드와 함께 사용할 수 있습니다.
- .split
- .스캔
- .gsub
- 및 기타...
예 :.scan을 사용하여 문자열의 모든 단어 일치
"this is some string".scan(/\w+/) # => ["this", "is", "some", "string"]
예 :문자열에서 모든 숫자 추출
"The year was 1492.".scan(/\d+/) # => ["1492"]
예 :문자열의 모든 단어를 대문자로
str = "lord of the rings" str.gsub(/\w+/) { |w| w.capitalize } # => "Lord Of The Rings"
예 :이메일 주소 확인
email = "[email protected]" !!email.match(/\A[\w.+-]+@\w+\.\w+\z/) # true
이 마지막 예제는 !!
를 사용합니다. 결과를 부울 값으로 변환(true
/ false
) 또는 match?
를 사용할 수 있습니다. 이미 이 작업을 수행하는 Ruby 2.4+의 메서드이며 더 빠릅니다.
결론
정규식은 훌륭하지만 때로는 약간 까다로울 수 있습니다. rubular.com과 같은 도구를 사용하면 ruby regex를 빌드하는 데 도움이 됩니다. 더 인터랙티브한 방식으로. Rubular에는 또한 매우 유용할 Ruby 정규식 치트 시트가 포함되어 있습니다. 이제 편집기를 열고 코딩을 시작할 차례입니다!
아, 잊지 마세요. 공유 재미있게 보셨다면 더 많은 분들이 배울 수 있도록 친구들과 함께 🙂