실제 언어는 렉서가 가야합니다 - like Guss said. 이 많이받지 않을 것 - 비록 당신이이 메소드는 충분 정규 언어를 분석하려는 경우
irb> text = %{Children^10 Health "sanitation management"^5}
irb> text.scan(/(?:(\w+)|"((?:\\.|[^\\"])*)")(?:\^(\d+))?/).map do |word,phrase,boost|
{ :keywords => (word || phrase).downcase, :boost => (boost.nil? ? nil : boost.to_i) }
end
#=> [{:boost=>10, :keywords=>"children"}, {:boost=>nil, :keywords=>"health"}, {:boost=>5, :keywords=>"sanitation management"}]
: 전체 언어가 예로서 복잡 전용으로 경우에, 당신이 빠른 해킹을 사용할 수 있습니다 언어를 비정규 화하기 위해 더 많은 합병증이 있습니다.
정규식의 빠른 고장 :
\w+
는
(?:\\.|[^\\"]])*
비 캡처 괄호 ((?:...)
)는 이스케이프 이중 인용 된 문자열의 내용과 일치하기 위해 사용하는 단일 용어 키워드와 일치 - 어느 쪽 탈출 기호 (\n
, \"
, \\
등) 또는 이스케이프 기호 또는 끝 인용 부호가 아닌 임의의 단일 문자.
"((?:\\.|[^\\"]])*)"
은 인용 된 키워드 구문의 내용 만 캡처합니다. 숫자와 일치 $2
\d+
에 $1
및 구문 내용에 하나의 용어를 포착, 하나의 단어 나 구 -
(?:(\w+)|"((?:\\.|[^\\"])*)")
는 키워드와 일치합니다.
\^(\d+)
은 캐럿 (^
) 뒤에 오는 번호를 캡처합니다. 이것이 캡쳐 링 괄호의 세 번째 세트이기 때문에, $3
에 caputred 될 것입니다.
(?:\^(\d+))?
은 캐럿 다음에 오는 번호를 캡처하고, 그렇지 않으면 빈 문자열과 일치시킵니다.
String#scan(regex)
은 "matches"의 배열을 출력하면서 가능한 한 여러 번 문자열에 대해 정규 표현식을 찾습니다. 정규식에 캡처 괄호가 포함되어 있으면 "일치"는 캡처 된 항목의 배열이므로 match[0]
, $2
이 match[1]
이됩니다.문자열의 일부와 일치하지 않는 모든 캡처 괄호는 결과 "일치"의 nil
항목에 매핑됩니다.
#map
다음 일치를 취하고 캡처 된 각 용어를 다른 변수로 나누기 위해 블록 마법을 사용하고 (do |match| ; word,phrase,boost = *match
일 수 있음) 원하는 해시를 만듭니다. word
또는 phrase
중 하나가 nil
이됩니다. 둘 모두를 입력과 비교할 수 없으므로 (word || phrase)
은 nil
이 아닌 값을 반환하고 #downcase
은 모두 소문자로 변환합니다. boost.to_i
은 문자열을 정수로 변환하고 (boost.nil? ? nil : boost.to_i)
은 nil
부스트가 nil
으로 유지되도록합니다.
코드에서 사용하는 경우 // x를 사용하고 주석을 추가 할 수 있습니다. – rampion
가능하다면 2 개의 upvotes를 줄 것입니다. 실용적인 접근을 위해 1 개, 잘 설명 된 정규식을 위해 1 개. – slothbear