2013-07-12 45 views
0

考慮以下字符串,它是從pdf中提取的內容表,如下例所示,兩個主題可以在一行上,在結尾處有一個換行符(在本例等)每行用正則表達式從一個大字符串中提取數據

A — N° 1 2 janvier 2013 

TABLE OF CONTENT 

Topic à one ......... 30 Second Topic .......... 33 
Third - one ......... 3 Topic.with.dots .......... 33 
One more line ......................... 27 last topic ...... 34 

我想提取部分的名稱「主題一」,「第二個主題」,「三酮」,「Topic.with.dots」,「一多行'和'最後一個主題'

任何見解匹配的正則表達式?

+1

您使用哪種正則表達式引擎?請始終爲任何正則表達式問題添加相應的標籤。謝謝! –

+1

部分名稱中允許使用哪些字符? –

+0

@Tim我使用Ruby 2 – denisjacquemin

回答

2
# -*- coding: utf-8 -*- 
string = "A — N° 1 2 janvier 2013 

TABLE OF CONTENT 

Topic à one ......... 30 Second Topic .......... 33 
Third - one ......... 3 Topic.with.dots .......... 33 
One more line ......................... 27 last topic ...... 34" 
puts string.scan(/(\p{l}[\p{l} \.-]*)\s+\.+\s+\d+/i).flatten 

這你想要做什麼。它也匹配單個字母的標題。

+1

我建議在第一個'+'之後加一個'?',也許使用'[\ t]'而不是'\ s',並使用'/ i'。 – Qtax

+0

@Qtax爲什麼[\ t]而不是\ s? –

+0

因此,一場比賽不能花費多行(在一些奇怪的文字的情況下)。 – Qtax

1

下(未優化還)正則表達式適用於你的例子:

(?i)(?=[A-Z])(?:\.[A-Z-]+|[A-Z -]+)+\b 

它需要改進,但是,例如,如果非ASCII字符應匹配,並且有依賴於一些可能的性能優化使用確切的正則表達式風味。

See it on regex101

紅寶石2,我建議/(?=\p{L})(?:\.[\p{L}-]++|[\p{L} -]+)+\b/

-1

下面是Perl中的一個解決方案:

$ cat tmp 
Topic one ......... 30 Second Topic .......... 33 Third one ......... 3 Topic.with.dots .......... 33 One more line ......................... 27 last topic ...... 34 


$ cat tmp | perl -ne 'while (m/((?:\w|[. ])+?) [.]+ \d+/g) { print "$1\n" }' 
Topic one 
Second Topic 
Third one 
Topic.with.dots 
One more line 
last topic 

的,我在這裏做什麼一點解釋,內套括號(?:...)都是非捕獲,所以他們只是用於分組,他們組詞-char(\w)或空格或點[. ]然後,由於您有更多的點,所以匹配是非貪婪的+?並且整個匹配進入打印的$1

HTH

- 編輯 -

Ruby有Perl的幾乎所有的結構,包括正則表達式,它是一個 直接的轉換! (!不知道爲什麼它不得不被否決) FWIW,這裏是用Ruby:

while ARGF.gets 
    puts $_.scan(/((?:\w|[. ])+?) [.]+ \d+/) 
end 
+1

雖然有效,OP請求一個Ruby解決方案。 –

+0

@theTinMan來吧,正則表達式是一個正則表達式。在另一種語言中使用正則表達式通常不是一個大問題。 – rednaw

+0

Onigmo只是PCRE的一個子集。 – sawa

1
string.scan(/(\S.*?)\s+\.{2,}\s+\d+/).flatten 
# => 
[ 
    "Topic one", 
    "Second Topic", 
    "Third one", 
    "Topic.with.dots", 
    "One more line", 
    "last topic" 
] 
1

類似@澤的​​:

puts text.scan(/([a-zA-Z .]+?) \.\.++ \d+/).flatten.map(&:strip) 
# >> Topic one 
# >> Second Topic 
# >> Third one 
# >> Topic.with.dots 
# >> One more line 
# >> last topic 

(我喜歡他的模式雖然好)