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 à one'、'Second Topic'、'Third -one'、'Topic.with.dots'、'One more line'和'last topic'

匹配正则表达式的任何见解?

4

5 回答 5

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

这可以满足您的需求。它还匹配单字母标题。

于 2013-07-12T08:24:20.863 回答
1

以下(尚未优化)正则表达式适用于您的示例:

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

但是,它需要改进,例如是否应该匹配非 ASCII 字母,并且有一些可能的性能优化取决于所使用的确切正则表达式风格。

在 regex101 上查看

对于 Ruby 2,我建议/(?=\p{L})(?:\.[\p{L}-]++|[\p{L} -]+)+\b/

于 2013-07-12T08:20:39.167 回答
1
string.scan(/(\S.*?)\s+\.{2,}\s+\d+/).flatten
# =>
[
  "Topic one",
  "Second Topic",
  "Third one",
  "Topic.with.dots",
  "One more line",
  "last topic"
]
于 2013-07-12T08:40:54.020 回答
1

类似于@sawa 的:

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

(不过我更喜欢他的模式。)

于 2013-07-12T08:51:00.257 回答
-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

稍微解释一下我在这里做什么,内部的括号集(?:...)是非捕获的,所以它们仅用于分组,它们将一个字字符(\w)或一个空格或点分组,[. ]然后,因为你有更多的点,匹配是非贪婪+?的,整个匹配进入$1,打印出来。

高温高压

- 编辑 -

Ruby 几乎具有 Perl 的所有构造,包括正则表达式,而且它是一种直接的转换!(不知道为什么它必须被否决!) FWIW,这里是 Ruby:

while ARGF.gets
  puts $_.scan(/((?:\w|[. ])+?) [.]+ \d+/)
end
于 2013-07-12T08:26:27.053 回答