Использование RegEx для извлечения имен и рангов в Python - PullRequest
1 голос
/ 27 сентября 2019

Я пытаюсь извлечь из базы данных следующую информацию:

  • Год (один раз)
  • Имена
  • Ранг

Сложная часть игнорирует некоторые части при извлечении других.

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

Popularity in 2018
Rank    Male name   Number of males     Female name     Number of females
1       Liam        19,837              Emma            18,688
2       Noah        18,267              Olivia          17,921
3       William     14,516              Ava             14,924
4       James       13,525              Isabella        14,464
5       Oliver      13,389              Sophia          13,928
6       Benjamin    13,381              Charlotte       12,940
7       Elijah      12,886              Mia             12,642
8       Lucas       12,585              Amelia          12,301
9       Mason       12,435              Harper          10,582
10      Logan       12,352              Evelyn          10,376
import re

year = r'\d{4}'
name = r'[A-Z][a-z].*$'
rank = r'\d{1,3}'

def extract_names(f):
    match_x = re.search(year, f)
    match_y = re.search(name, f)
    match_z = re.search(rank, f)
    x = match_x.group()
    y = match_y.groups()
    z = match_z.groups()

    def print_match(x, y=False, z=False):
        if match_y and match_z:
            print(x, y, z)
        elif match_y:
            print(x, y, 'is unranked')
        else:
            print("No match found for year", x)

    print_match(x, y, z + ".")

Я получаюнесколько разных ошибок с несколькими разными кодами, но я хочу вытащить словарь (названный по году) и затем имя с рангом

Идея состоит в том, чтобы вытащить информацию так, чтобы яможно назвать одно имя, скажем, «Лиам», и это дает общую тенденцию за годы популярности имени Лиам.

Помогите!:)

Ответы [ 2 ]

0 голосов
/ 28 сентября 2019

Вы можете сделать это простым REGEX r'(\d{4})|(?<=\n)(\d+)\s+(\w+)':

import re

text ="""
Popularity in 2018
Rank    Male name   Number of males     Female name     Number of females
1       Liam        19,837              Emma            18,688
2       Noah        18,267              Olivia          17,921
3       William     14,516              Ava             14,924
4       James       13,525              Isabella        14,464
5       Oliver      13,389              Sophia          13,928
6       Benjamin    13,381              Charlotte       12,940
7       Elijah      12,886              Mia             12,642
8       Lucas       12,585              Amelia          12,301
9       Mason       12,435              Harper          10,582
10      Logan       12,352              Evelyn          10,376
""".strip()
year = '(\d{4})'
rank_name = '(?<=\n)(\d+)\s+(\w+)'
pattern = r'{}|{}'.format(year, rank_name)
for match in re.finditer(pattern, text):
    year, rank, name = match.groups()
    if year:
        print('Year is: ', year)
    else:
        print('Name {} RANK: {}'.format(name, rank))

ВЫХОД:

Year is:  2018
Name Liam RANK: 1
Name Noah RANK: 2
Name William RANK: 3
Name James RANK: 4
Name Oliver RANK: 5
Name Benjamin RANK: 6
Name Elijah RANK: 7
Name Lucas RANK: 8
Name Mason RANK: 9
Name Logan RANK: 10

Здесь у каждого матча есть 3 группы, содержащие либо год, либо имя и ранг.

0 голосов
/ 27 сентября 2019

Не думайте, что вам нужно регулярное выражение, поскольку данные довольно регулярные.Цикл по линиям может работать.

db = '''Popularity in 2018
Rank    Male name   Number of males     Female name     Number of females
1       Liam        19,837              Emma            18,688
2       Noah        18,267              Olivia          17,921
3       William     14,516              Ava             14,924
4       James       13,525              Isabella        14,464
5       Oliver      13,389              Sophia          13,928
6       Benjamin    13,381              Charlotte       12,940
7       Elijah      12,886              Mia             12,642
8       Lucas       12,585              Amelia          12,301
9       Mason       12,435              Harper          10,582
10      Logan       12,352              Evelyn          10,376 '''
lines = db.split('\n')
year = lines[0].split(' ')[-1]
for line in lines[2:]:
    data = list(filter(None, line.split(' ')))
    rank, male, female = data[0], data[1], data[3]

Я думаю, что интервал между столбцами на самом деле является вкладками, так что это даже проще, и вы можете просто разделить на \t.

ПослеТаким образом, вы можете сохранить информацию, как вы хотите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...