Python 从段落中提取信息



我是Python的新手,现在我正在尝试从一组包含员工相关统计数据的段落中提取信息。

例如,该段落可能如下所示:

姓名 Rakesh Rao 年龄 34 性别 男性 婚姻状况 单身

整个文本没有被任何逗号分隔,所以我很难将这些信息分开。 此外,有时变量名称后可能会有一个冒号,有时可能没有。例如,在第 1 行中,它是"Name Rakesh Rao",但在第 2 行中它是"Name: Ramachandra Deshpande"

这些信息大约有 1400 条记录,因此如果我不必手动分离信息,那就太好了。 谁能帮忙?我将非常感激!

好吧,我想你可以尝试使用正则表达式来做到这一点。 如果你的文字正是这样:

paragraph = 'Name Rakesh Rao Age 34 Gender Male Marital Status Single'

您可以使用此正则表达式(必须先import re(:

m = re.fullmatch(
(
r'Name(?::)? (?P<name>D+) '  # pay attention to the space at the end
r'Age(?::)? (?P<age>d+) '
r'Gender(?::)? (?P<gender>D+) '
r'Marital Status(?::)? (?P<status>D+)'  # no space here, since the string ends
),
paragraph
)

然后,您可以使用正则表达式中定义的组的名称,如下所示:

>>> m.group('name')
'Rakesh Rao'
>>> m.group('age')
'34'
>>> m.group('gender')
'Male'
>>> m.group('status')
'Single'

如果所有字段都在一行中,则只需将n替换为正则表达式中的单个空格即可。

请注意,这将支持紧跟在行名后面的单个逗号,如下所示:

Name: Rakesh Rao

但它不支持不同的数据顺序。如果你也愿意,我可以尝试写一个不同的表达式。

表达式的解释

让我们取表达式的第一"行":

r'Name(?::)? (?P<name>D+) '

首先,为什么r'…'字符串语法?这只是为了避免双反斜杠。在"典型"字符串中,我们需要像这样编写表达式:

'Name(?:\:)? (?P<name>\D+) '

现在,到实际的表达。第一部分,Name,很明显。

(?::)?

这部分创建了一个内部带有冒号的非捕获组((?:…)- 它是:而不仅仅是:,因为冒号本身是正则表达式语法的一部分。非捕获组,因为这个冒号对我们来说真的无关紧要。

然后,在单个空格之后,我们有这个:

(?P<name>D+)

这将创建一个命名组,语法为(?P<name_of_the_group>…)。我使用命名组只是为了方便以后使用m.group('name')提取信息,其中m是一个匹配对象。

D+表示"至少一个非数字字符"。这将捕获所有字母、下划线以及空格。这就是为什么字段的顺序对于这个特定的表达式如此重要的原因。如果您要更改顺序并将Gender字段放在NameAge之间,它也会捕获它,因为+修饰符是贪婪的。

另一方面,下一个"行"中的d+表示"至少一个数字字符",因此介于 0 和 9 之间。

我希望这个解释就足够了,但在这个非常有用的网站上,在这里玩这个表达式可能对你有用:

https://regex101.com/r/N5ZJU9/2

我已经为您输入了正则表达式和测试字符串。

您可以匹配可选字符,在您的情况下,使用以下表达式[:]?:

根据提供的信息,此正则表达式应提取所需的信息:

^Name[:]?s([A-Z][-'a-zA-Z]+)s([A-Z][-'a-zA-Z]+)$

你可以在这里查看。 此正则表达式将匹配两个单词的名称。还包含-'的名称。 在 Python 中,这可能看起来像这样:

regex = r"^Name[:]?s([A-Z][-'a-zA-Z]+)s([A-Z][-'a-zA-Z]+)$"    
test_str = ("Name Rakesh Raon"
"Name: Ramachandra Deshpande")    
matches = re.finditer(regex, test_str, re.MULTILINE)

您也可以通过上面提供的链接查看此示例。

希望这有帮助。

如果字段名称始终在字符串中,则可以拆分这些字段名称上的字符串。例如:

str_to_split = "Name Rakesh Rao Age 34 Gender Male Marital Status Single"
splitted = str_to_split.split("Age")
name = splitted[0].replace("Name", "")

例如,如果您的文本仍包含其他字符,则可以使用replace(":", "")删除它们。否则,您可以使用 NLTK 工具包从文本中删除所有类型的特殊字符。要小心,因为名称中也可能包含特殊的字符。

最新更新