2015-01-15 59 views
1

我想匹配貪婪匹配如下:正則表達式非跨換行符

str = "---title: Some Title\ndate: 01/01/2012---\n\nSome other stuff---\n\n" 

而且我想獲得:

"title: Some Title\ndate: 01/01/2012" 

所以,我想出了正則表達式爲:

~r/---(.+)---(.+)/s 

不幸的是,貪婪和匹配:

"title: Some Title\ndate: 01/01/2012---\n\nSome other stuff" 

我也嘗試了非貪婪操作和失敗過:

(~r/---(.+)---(.+)?.*/s 

任何建議將是超級有用。

感謝

+0

我刪除了Perl和PCRE標籤,因爲它們不是問題的關鍵。 –

+0

我正在尋找PCRE'ish解決方案,因爲我使用的是Elixir,它有一個PCRE正則表達式引擎。因此,標籤。 – user3118605

回答

0

一個更通用的正則表達式是:

(?:---)?(?<key>[a-z]+)\s*:\s*(?<value>(?!\\n).+?)(?:\\n|---|$) 

它分割在關鍵比賽:值。

DEMO

+1

謝謝。我正在尋找一個通用的解決方案 - 即不是期望標題和日期在那裏的東西。我希望這可以在'---(這裏的一些東西)---'之間進行。 – user3118605

2

使用string.scan功能類似下面。

> 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" 

上述掃描函數的輸出是一個二維數組,因爲捕獲組的存在。 [\s\S]+?非貪婪地匹配一個或多個空格或非空格字符。請注意,此模式也將匹配換行符(\n\r)。

0

這裏的正確方法不是嘗試匹配要提取的部分,而是匹配要丟棄的部分並使用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" 
+0

謝謝,不過,我確實在尋找一個匹配捕獲解決方案。 – user3118605

0

如果你最終想要的標題和日期字符串,你不妨將它們拉出來直接:

str.scan(/---title:\s+([^\n]+)\ndate:\s+(\d{2}\/\d{2}\/\d{4})/) 
    #=> [["Some Title", "01/01/2012"]] 
+0

在這裏沒有必要看後面。只需按照正常的方式匹配那部分,並忽略它,就像你在'date:'部分做的一樣。 –

+0

謝謝,@Alan。我修好了它。一件小事,但取消了lookie也讓我把'title:\ s'改成'title:\ s +'。 [讀者:我以前有'(?<= --- title:\ s)'是一個(「零寬度」)「積極向後看」]。 –

0

一個Perl的方式來做到這一點:

#!/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; 

輸出:

title: Some Title 
date: 01/01/2012 
+0

太酷了!我知道我必須僱用一個非貪婪的運營商,以及一些匹配的新線。我想知道,爲什麼我們需要第二個「?」 「$」之前?難道不夠嗎? '〜r /---(.+?)---.*$/ s' 謝謝! – user3118605

+0

此外,它不得不**是貪婪?我不能這樣做,'regex =〜r/---([^ - {3}] +)---。* $/s'? – user3118605