Python 从段落中提取信息
Python extract information from paragraph
我是 Python 的新手,现在我正在尝试从一组包含员工相关统计数据的段落中提取信息。
例如,该段落可能如下所示:
Name Rakesh Rao Age 34 Gender Male Marital Status Single
整个文本没有用任何逗号分隔,所以我很难分隔这些信息。
此外,有时变量名称后可能有冒号,有时可能没有。例如在第 1 行中,它是 "Name Rakesh Rao"
但在第 2 行中它是 "Name: Ramachandra Deshpande"
.
这些信息大约有 1400 条记录,所以如果我不必手动分离信息就太好了。
有人能帮忙吗?我将不胜感激!
您可以匹配可选字符,在您的情况下它是 :
与以下表达式 [:]?
.
根据提供的信息,此正则表达式应提取所需信息:
^Name[:]?\s([A-Z][-'a-zA-Z]+)\s([A-Z][-'a-zA-Z]+)$
你可以查看一下here。
此正则表达式将匹配两个单词的名称。还有包含 -'
的名称。
在 Python 这可能看起来像这样:
regex = r"^Name[:]?\s([A-Z][-'a-zA-Z]+)\s([A-Z][-'a-zA-Z]+)$"
test_str = ("Name Rakesh Rao\n"
"Name: Ramachandra Deshpande")
matches = re.finditer(regex, test_str, re.MULTILINE)
您也可以通过上面提供的link查看此示例。
希望这对您有所帮助。
如果字段名总是在字符串中,您可以根据这些字段名拆分字符串。例如:
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 工具包从文本中删除所有类型的特殊字符。请注意,因为名称中也可能包含特殊字符。
好吧,我想您可以尝试使用正则表达式来做到这一点。
如果您的文字正是这样:
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
替换为单个 space。
请注意,这将支持在行名称后紧跟一个逗号,如下所示:
Name: Rakesh Rao
但不支持数据的不同顺序。如果你也想这样,我可以尝试写一个不同的表达式。
表达式的解释
让我们取表达式的第一个"line":
r'Name(?:\:)? (?P<name>\D+) '
首先,为什么使用 r'…'
字符串语法?这只是为了避免双反斜杠。在 "typical" 字符串中,我们需要这样写表达式:
'Name(?:\:)? (?P<name>\D+) '
现在,进入实际的表达。第一部分 Name
非常明显。
(?:\:)?
这部分创建了一个内部有冒号的非捕获组 ((?:…)
) – 它是 \:
而不仅仅是 :
,因为冒号本身是正则表达式语法的一部分.非捕获组,因为这个冒号对我们来说真的无所谓。
然后,在一个 space 之后,我们有这个:
(?P<name>\D+)
这将创建一个命名组,语法为(?P<name_of_the_group>…)
。我使用命名组只是为了让以后更容易和更好地提取信息,使用 m.group('name')
,其中 m
是一个匹配对象。
\D+
表示 "at least one non-digit character"。这会捕获所有字母、下划线,但也会捕获白色 space。这就是字段顺序对于这个特定表达式如此重要的原因。如果您要更改顺序并将 Gender
字段放在 Name
和 Age
之间,它也会捕获它,因为 +
修饰符是贪婪的。
另一方面,下一个 "line" 中的 \d+
表示 "at least one digit character",因此介于 0 和 9 之间。
我希望这个解释足够了,但在这个非常有用的网站上使用这个表达可能对您有用:
https://regex101.com/r/N5ZJU9/2
我已经为你输入了正则表达式和测试字符串。
我是 Python 的新手,现在我正在尝试从一组包含员工相关统计数据的段落中提取信息。
例如,该段落可能如下所示:
Name Rakesh Rao Age 34 Gender Male Marital Status Single
整个文本没有用任何逗号分隔,所以我很难分隔这些信息。
此外,有时变量名称后可能有冒号,有时可能没有。例如在第 1 行中,它是 "Name Rakesh Rao"
但在第 2 行中它是 "Name: Ramachandra Deshpande"
.
这些信息大约有 1400 条记录,所以如果我不必手动分离信息就太好了。 有人能帮忙吗?我将不胜感激!
您可以匹配可选字符,在您的情况下它是 :
与以下表达式 [:]?
.
根据提供的信息,此正则表达式应提取所需信息:
^Name[:]?\s([A-Z][-'a-zA-Z]+)\s([A-Z][-'a-zA-Z]+)$
你可以查看一下here。
此正则表达式将匹配两个单词的名称。还有包含 -'
的名称。
在 Python 这可能看起来像这样:
regex = r"^Name[:]?\s([A-Z][-'a-zA-Z]+)\s([A-Z][-'a-zA-Z]+)$"
test_str = ("Name Rakesh Rao\n"
"Name: Ramachandra Deshpande")
matches = re.finditer(regex, test_str, re.MULTILINE)
您也可以通过上面提供的link查看此示例。
希望这对您有所帮助。
如果字段名总是在字符串中,您可以根据这些字段名拆分字符串。例如:
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 工具包从文本中删除所有类型的特殊字符。请注意,因为名称中也可能包含特殊字符。
好吧,我想您可以尝试使用正则表达式来做到这一点。 如果您的文字正是这样:
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
替换为单个 space。
请注意,这将支持在行名称后紧跟一个逗号,如下所示:
Name: Rakesh Rao
但不支持数据的不同顺序。如果你也想这样,我可以尝试写一个不同的表达式。
表达式的解释
让我们取表达式的第一个"line":
r'Name(?:\:)? (?P<name>\D+) '
首先,为什么使用 r'…'
字符串语法?这只是为了避免双反斜杠。在 "typical" 字符串中,我们需要这样写表达式:
'Name(?:\:)? (?P<name>\D+) '
现在,进入实际的表达。第一部分 Name
非常明显。
(?:\:)?
这部分创建了一个内部有冒号的非捕获组 ((?:…)
) – 它是 \:
而不仅仅是 :
,因为冒号本身是正则表达式语法的一部分.非捕获组,因为这个冒号对我们来说真的无所谓。
然后,在一个 space 之后,我们有这个:
(?P<name>\D+)
这将创建一个命名组,语法为(?P<name_of_the_group>…)
。我使用命名组只是为了让以后更容易和更好地提取信息,使用 m.group('name')
,其中 m
是一个匹配对象。
\D+
表示 "at least one non-digit character"。这会捕获所有字母、下划线,但也会捕获白色 space。这就是字段顺序对于这个特定表达式如此重要的原因。如果您要更改顺序并将 Gender
字段放在 Name
和 Age
之间,它也会捕获它,因为 +
修饰符是贪婪的。
另一方面,下一个 "line" 中的 \d+
表示 "at least one digit character",因此介于 0 和 9 之间。
我希望这个解释足够了,但在这个非常有用的网站上使用这个表达可能对您有用:
https://regex101.com/r/N5ZJU9/2
我已经为你输入了正则表达式和测试字符串。