使用正则表达式从一个大字符串中提取数据

时间:2013-07-12 08:13:49

标签: ruby regex

考虑以下String,它是从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'

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

5 个答案:

答案 0 :(得分: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 :(得分:1)

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

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

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

See it on regex101

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

答案 2 :(得分:1)

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

答案 3 :(得分: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

(虽然我更喜欢他的模式。)

答案 4 :(得分:-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

我在这里做的一些小解释,内部的parens (?:...)集合是非捕获的,因此它们仅用于分组,并且它们组合了一个单词char(\w)或者空格或点[. ]然后,由于你有更多的点,匹配是非贪婪的+?,整个匹配进入$1,打印出来。

HTH

<强> - 编辑 -

Ruby几乎拥有Perl的所有构造,包括正则表达式,它是一个 直接转换! (不知道为什么它必须被投票!) FWIW,这是Ruby:

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