Python извлекать информацию из абзаца - PullRequest
1 голос
/ 14 октября 2019

Я новичок в Python и сейчас пытаюсь извлечь информацию из набора параграфов, содержащих статистику, относящуюся к сотрудникам.

Например, абзац может выглядеть так:

Имя Ракеш Рао Возраст 34 Пол Мужской Семейное положение Холост

Весь текст не разделен комами, поэтому мне трудно отделить эту информацию. Также иногда может быть двоеточие после имени переменной, а иногда его может и не быть. Например, в строке 1 это "Name Rakesh Rao", но в строке 2 это "Name: Ramachandra Deshpande".

Существует около 1400 записей этой информации, поэтому было бы здорово, если бы мне не приходилось вручную отделять информацию,Может кто-нибудь помочь с этим? Я был бы очень благодарен!

Ответы [ 3 ]

1 голос
/ 14 октября 2019

Ну, я полагаю, вы можете попытаться сделать это с помощью регулярного выражения. Если ваш текст в точности такой:

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 между Name и Age, оно также захватило бы его, потому что модификатор + жадный.

С другой стороны,\d+ в следующей «строке» означает «хотя бы один символ», поэтому от 0 до 9.

Надеюсь, этого объяснения достаточно, но вам может быть полезно поиграть с этим выражением здесь, на этом очень полезном сайте:

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

Я уже ввел регулярное выражение и тестовую строку для вас.

0 голосов
/ 14 октября 2019

Если имена полей всегда находятся в строке, вы можете разбить строку на эти имена полей. Например:

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, чтобы удалить все виды специальных символов из вашего текста. Будьте осторожны, потому что в именах также могут быть специальные символы.

0 голосов
/ 14 октября 2019

Вы можете сопоставить необязательные символы, в вашем случае это : со следующим выражением [:]?.

Согласно предоставленной информации, это регулярное выражение должно извлечь необходимую информацию:

^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 Rao\n"
    "Name: Ramachandra Deshpande")    
matches = re.finditer(regex, test_str, re.MULTILINE)

Этот пример также можно проверить по приведенной выше ссылке.

Надеюсь, это поможет.

...