Regex to capture colon-separated key-value pairs, with multi-line values
eclipse, regex, ruby, ruby-on-rails
Solution
Given the clarified question, here's a new solution.
UPDATED
"Slurp" the entire block of data (including the newline characters and all) into a single string, first.
str = IO.read("report.rtf")
Then use this regex:
captures = str.scan(/(?<=^|[\r\n])([A-Z][^:]*):([^\r\n]*(?:[\r\n]+(?![A-Z].*:).*)*)/)
See a live example here: http://rubular.com/r/8w3X6WGq4l.
The answer, explained:
(?<= Lookbehind assertion.
^ Start at the beginning of the string,
| or,
[\r\n] a new line.
)
( Capture group 1, the "key".
[A-Z][^:]* Capital letter followed as many non-colon
characters as possible.
)
: The colon character.
( Capture group 2, the "value".
[^\r\n]* All characters (i.e. non-newline characters) on the
same line belongs to the "value," so take them all.
(?: Non-capture group.
[\r\n]+ Having already taken everything up to a newline
character, take the newline character(s) now.
(?! Negative lookahead assertion.
[^A-Z].*: If this next line contains a capital letter,
followed by a string of anything then a colon,
then it is a new key/value pair, so we do not
want to match this case.
)
.* Providing this isn't the case though, take the line!
)* And keep taking lines as long as we don't find a
key/value pair.
)
Problem
I'm currently working on a project in Ruby on Rails (in Eclipse) and my task is to split up a block of data into relevant parts using Regular Expressions. I've decided to break up the data based on 3 parameters: - The line must start with a capital letter (RegEx equivalent - `/^[A-Z]/`) - It must end with a : (RegEx equivalent - `/$":"/`) I would appreciate any help....The code I'm using in my controller is: ``` @f = File.open("report.rtf") @fread = @f.read @chunk = @fread.split(/\n/) ``` where `@chunk` is the array that will be created by the split and `@fread` is the data that is being split up (by new lines). Any help will be appreciated, thanks a lot! I cannot release the exact data but it goes basically by this (this is medically related) Exam 1: CBW 8080 RESULT: This report is dictated with specific measurement. Please see the original report. COMPARISON: 1/30/2012, 3/8/12, 4/9/12 RECIST 1.1: BLAH BLAH BLAH The ideal output would be an array that says: ``` ["Exam 1:", "CBW 8080", "RESULT", "This report is dictated with specific measurement. Please see the original report.", "COMPARISON:", "1/30/2012, 3/8/12, 4/9/12", "RECIST 1.1:", "BLAH BLAH BLAH"] ``` PS I'm just using \n as a placeholder until I get it working