Reputation: 41
I am trying to match the following:
str = "---title: Some Title\ndate: 01/01/2012---\n\nSome other stuff---\n\n"
And I would like to get:
"title: Some Title\ndate: 01/01/2012"
So, the regex I came up with was:
~r/---(.+)---(.+)/s
It's unfortunately, being greed and matching:
"title: Some Title\ndate: 01/01/2012---\n\nSome other stuff"
I also tried the non-greedy operator and that failed too:
(~r/---(.+)---(.+)?.*/s
Any suggestions would be super helpful.
Thanks
Upvotes: 1
Views: 913
Reputation: 4887
A more generic regex is:
(?:---)?(?<key>[a-z]+)\s*:\s*(?<value>(?!\\n).+?)(?:\\n|---|$)
It splits the match in key:value.
Upvotes: 0
Reputation: 110675
If you ultimately want the title and date string, you may as well pull them out directly:
str.scan(/---title:\s+([^\n]+)\ndate:\s+(\d{2}\/\d{2}\/\d{4})/)
#=> [["Some Title", "01/01/2012"]]
Upvotes: 0
Reputation: 91385
A perl way to do it:
#!/usr/bin/perl
use Modern::Perl;
my $str = "---title: Some Title\ndate: 01/01/2012---\n\nSome other stuff---\n\n";
$str =~ s/---(.+?)---.*?$/$1/s;
say $str;
Output:
title: Some Title
date: 01/01/2012
Upvotes: 0
Reputation: 168081
The right way here is not to try to match the part you want to extract, but match the part you want to throw away and use split
.
s.split(/---\n*/)
#=> ["", "title: Some Title\ndate: 01/01/2012", "Some other stuff"]
str.split(/---\n*/)[1]
#=> "title: Some Title\ndate: 01/01/2012"
Upvotes: 0
Reputation: 174696
Use string.scan
function like below.
> str = "---title: Some Title\ndate: 01/01/2012---\n\nSome other stuff---\n\n"
> str.scan(/---([\s\S]+?)---/)[0][0]
=> "title: Some Title\ndate: 01/01/2012"
Output of the above scan function is a two dimensional array is because of the existence of capturing group. [\s\S]+?
Matches one or more space or non-space characters non-greedily. Note that this pattern would also match the line breaks (\n
, \r
).
Upvotes: 2
Reputation: 67968
---(?:(?!---).)*---
Try this.See demo.
https://regex101.com/r/fA6wE2/34
Upvotes: 0