Извлечение идентификаторов пользователей из файла .csv - PullRequest
0 голосов
/ 08 апреля 2019

У меня есть CSV-файл с информацией о пользователе. Пример из файла, как показано ниже.

 "userType": "NORMAL",   "accountID": "J123456789"
 "userType": "NORMAL",   "accountID": "J987654321"
 "userType": "NORMAL",   "accountID": "C123456789"
 "userType": "NORMAL",   "accountID": "R987654321"

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

Регулярное выражение, которое я использовал, было ("accountID": ")\w+, и оно дает следующий результат.

"accountID": "J123456789
"accountID": "J987654321
"accountID": "C123456789
"accountID": "R987654321

Желаемый результат должен быть следующим:

J987654321
J987654321
C123456789
R987654321

Ответы [ 4 ]

0 голосов
/ 08 апреля 2019

Вы можете написать себе синтаксический анализатор (хотя, возможно, немного перегружен):

from parsimonious.grammar import Grammar
from parsimonious.nodes import NodeVisitor

text = """
 "userType": "NORMAL",   "accountID": "J123456789"
 "userType": "NORMAL",   "accountID": "J987654321"
 "userType": "NORMAL",   "accountID": "C123456789"
 "userType": "NORMAL",   "accountID": "R987654321"
"""

grammar = Grammar(
    r"""
    file        = entry+

    entry       = garbage? (pair)+ newline
    pair        = ws? key equal value comma?

    key         = quotes word quotes
    value       = quotes word quotes
    quotes      = '"'
    word        = ~"\w+"
    equal       = ws? ":" ws?
    comma       = ws? "," ws?

    ws          = ~"[\t ]+"
    newline     = ~"[\r\n]"
    garbage     = (ws / newline)+
    """
)

tree = grammar.parse(text)

class Vistor(NodeVisitor):
    def __init__(self, needle):
        self.needle = needle

    def generic_visit(self, node, visited_children):
        return visited_children or node

    def visit_key(self, node, children):
        _, key, _ = children
        return key

    def visit_value(self, node, children):
        _, value, _ = children
        return value

    def visit_pair(self, node, children):
        _, key, _, value, _ = children
        return (key, value)

    def visit_entry(self, node, children):
        _, entry, _ = children
        return entry

    def visit_file(self, node, children):
        out = [value.text
               for child in children if isinstance(child, list)
               for key, value in child
               if key.text == self.needle]
        return out

v = Vistor("accountID")
out = v.visit(tree)
print(out)

Что дает

['J123456789', 'J987654321', 'C123456789', 'R987654321']
0 голосов
/ 08 апреля 2019

вы можете использовать следующее регулярное выражение "(?:\"accountID\": \")(\S+)\", которое получает только идентификаторы и игнорирует оставшуюся часть

import re

s = """"userType": "NORMAL",   "accountID": "J123456789"
 "userType": "NORMAL",   "accountID": "J987654321"
 "userType": "NORMAL",   "accountID": "C123456789"
 "userType": "NORMAL",   "accountID": "R987654321" """

print(re.findall("(?:\"accountID\": \")(\S+)\"",s))

результат:

['J123456789', 'J987654321', 'C123456789', 'R987654321']
0 голосов
/ 08 апреля 2019

Имхо, это вообще не требует импорта:

with open('test.csv') as f:
    for line in f:
        print(line.strip()[-11:-1])

или, если длина идентификаторов учетной записи действительно различается, используйте:

        print(line.split('"')[-2])

внутри цикла.

0 голосов
/ 08 апреля 2019

Если формат файла фиксированный, рассмотрите возможность автоматического определения диалекта:

import csv

with open('test.csv') as csvfile:
    dialect = csv.Sniffer().sniff(csvfile.read(1024))
    csvfile.seek(0)
    reader = csv.reader(csvfile, dialect)
    accounts = [row[2] for row in reader]

Этот код выдаст следующий список:

accounts
['J000025574', 'J000025620', 'C000025623', 'R000025624']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...