Your regular expression /^[^\\]+/
attempts to match one or more characters at the beginning of a line that are not backslashes. The backslash character (ASCII 92) is written 92.chr #=> "\\"
, whereas the line feed character (ASCII 13) is written 13.chr #=> "\r"
.1
You therefore want /\A[^\r]+/
.
Note that I've used the beginning of string anchor, \A
, rather than the beginning of line anchor, ^
. Consider the following.
"\r\ndog \r".match(/\A[^\r]+/) #=> nil
"\r\ndog \r".match(/^[^\r]+/) #=> #<MatchData "dog ">
Whether to use \A
or ^
depends on what you want to achieve. Henceforth I will assume it is \A
that you want. (You should make that clear, however, by editing the question. As written, the desired substring need not start at the beginning of the string or a line.)
Continuing,
r = /\A[^\r]+/
m = s.match(r) #=> #<MatchData "Shadowborn Apostle ">
m[0] #=> "Shadowborn Apostle "
or (in place of m[0]
):
$& #=> "Shadowborn Apostle "
or simply:
s[r] #=> "Shadowborn Apostle "
See MatchData#[] and String#[].
If the ending space is optional this is fine. If, however, the string must end with a space, we must make a slight adjustment to the regex:
r = /\A[^\r]+ /
Lastly, here is another way to obtain the desired substring that does not use a regular expression:
idx = s.index(" \r")
#=> 18
idx.nil? ? nil : s[0, idx+1]
#=> "Shadowborn Apostle "
idx = "How now, brown cow".index(" \r")
#=> nil
idx.nil? ? nil : s[0,idx+1]
#=> nil
See String#index.
1 Why not a single backslash (/^[^\]+/
)? Because Ruby would start the character class ("["
), read 'negate' ("^"
) an escaped right bracket "\]"
(interpreted as the character "]"
), and "+"
. As the next character, "/"
, terminates the regular expression, she would conclude that the character class was not closed and therefore raise an exception (SyntaxError
).