манипулирование и обработка строк Python - PullRequest
3 голосов
/ 26 марта 2012

У меня есть несколько кодов, которые мне нужно обработать, и они поступают в нескольких различных форматах, которыми мне нужно сначала манипулировать, чтобы получить их в правильном формате:

Примеры кодов:

ABC1.12 - correct format
ABC 1.22 - space between letters and numbers
ABC1.12/13 - 2 codes joined together and leading 1. missing from 13, should be ABC1.12 and ABC1.13 
ABC 1.12 / 1.13 - codes joined together and spaces

Я знаю, как убрать пробелы, но не уверен, как обращаться с кодами, которые были разбиты. Я знаю, что могу использовать функцию split для создания 2 кодов, но не уверен, каким образом я могу добавить буквы (и первую часть числа) ко второму коду. Это 3-й и 4-й пример в списке выше.

Что у меня так далеко

    val = # code
    retList = [val]
    if "/" in val:
        (code1, code2) = session_codes = val.split("/", 1)

        (inital_letters, numbers) = code1.split(".", 1)
        if initial_letters not in code2:
            code2 = initial_letters + '.' + code2

        # reset list so that it returns both values 
        retList = [code1, code2]

Это на самом деле не будет обрабатывать разбиения для 4, так как code2 становится ABC1.1.13

Ответы [ 5 ]

3 голосов
/ 26 марта 2012

Вы можете использовать регулярные выражения для этой цели

Возможная реализация будет выглядеть следующим образом

>>> def foo(st):
    parts=st.replace(' ','').split("/")
    parts=list(re.findall("^([A-Za-z]+)(.*)$",parts[0])[0])+parts[1:]
    parts=parts[0:1]+[x.split('.') for x in parts[1:]]
    parts=parts[0:1]+['.'.join(x) if len(x) > 1 else '.'.join([parts[1][0],x[0]]) for x in parts[1:]]
    return [parts[0]+p for p in parts[1:]]

>>> foo('ABC1.12')
['ABC1.12']
>>> foo('ABC 1.22')
['ABC1.22']
>>> foo('ABC1.12/13')
['ABC1.12', 'ABC1.13']
>>> foo('ABC 1.12 / 1.13')
['ABC1.12', 'ABC1.13']
>>> 
1 голос
/ 26 марта 2012

Вы знакомы с регулярным выражением? Это был бы угол, который стоит изучить здесь. Кроме того, рассмотрите возможность разделения по пробелу, а не только по косой и десятичной дроби.

0 голосов
/ 26 марта 2012

Взгляните на этот метод.Возможно, это самый простой и лучший способ сделать это.

val = unicode(raw_input())

for aChar in val:
    if aChar.isnumeric():
        lastIndex = val.index(aChar)
        break

part1 = val[:lastIndex].strip()
part2 = val[lastIndex:]

if "/" not in part2:
    print part1+part2
else:
    if " " not in part2:
        codes = []
        divPart2 = part2.split(".")
        partCodes = divPart2[1].split("/")
        for aPart in partCodes:
            codes.append(part1+divPart2[0]+"."+aPart)
        print codes
    else:
        codes = []
        divPart2 = part2.split("/")
        for aPart in divPart2:
            aPart = aPart.strip()
            codes.append(part1+aPart)
        print codes
0 голосов
/ 26 марта 2012

Использование PyParsing

Ответ @Abhijit хорош, и для этой простой проблемы reg-ex может быть подходящим вариантом. Однако при работе с проблемами анализа вам часто требуется более расширяемое решение, которое может расти вместе с вашей проблемой . Я обнаружил, что pyparsing отлично подходит для этого, вы пишете грамматику она выполняет анализ:

from pyparsing import *

index = Combine(Word(alphas))

# Define what a number is and convert it to a float
number = Combine(Word(nums)+Optional('.'+Optional(Word(nums))))
number.setParseAction(lambda x: float(x[0]))

# What do extra numbers look like?
marker = Word('/').suppress()
extra_numbers = marker + number

# Define what a possible line could be
line_code = Group(index + number + ZeroOrMore(extra_numbers))
grammar = OneOrMore(line_code)

Из этого определения мы можем разобрать строку:

S = '''ABC1.12
ABC 1.22
XXX1.12/13/77/32.
XYZ 1.12 / 1.13
'''
print grammar.parseString(S)

Предоставление:

[['ABC', 1.12], ['ABC', 1.22], ['XXX', 1.12, 13.0, 77.0, 32.0], ['XYZ', 1.12, 1.13]]

Преимущества:

Число теперь в правильном формате, так как мы набрали их как плавающие во время синтаксического анализа . Обрабатывается еще много «чисел», посмотрите на индекс «XXX», все числа типа 1.12, 13, 32 разбираются независимо от десятичного числа.

0 голосов
/ 26 марта 2012

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

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