2013-08-01 3 views
2

У меня проблема делать такую ​​операцию, скажем, у нас есть строкаPython строка, найти конкретное слово, а затем скопировать слово после

teststring = "This is a test of number, number: 525, number: 585, number2: 559" 

Я хочу, чтобы хранить 525 и 585 в список, как я могу сделать это?

Я сделал это очень глупо, работает, но там должен быть более эффективными способами

teststring = teststring.split() 
found = False 
    for word in teststring: 
     if found: 
      templist.append(word) 
      found = False 
     if word is "number:": 
      found = True 

Существуют ли решения с регулярным выражением?

Followup: Что делать, если я хочу хранить 525, 585 и 559?

+0

Почему вы хотите использовать регулярное выражение здесь?Простое понимание списка будет более быстрым и на самом деле читаемым – tobyodavies

+0

@tobyodavies вам понадобится несколько шагов, таких как разделение и числа разбора и т. Д.? – Guagua

ответ

4

re Используйте модуль:

>>> re.findall(r'number\d*: (\d+)',teststring) 
['525', '585', '559'] 

\d любая цифра [0-9]
* означает от 0 до бесконечности у раза
() означает, что захват
+ средства от 1 до времен бесконечности

Если вам нужно преобразовать сгенерированные строки в int с, используйте map:

>>> map(int, ['525', '585', '559']) 
[525, 585, 559] 

или

list comprehension:

>>> [int(s) for s in ['525', '585', '559']] 
[525, 585, 559] 
+0

Привет, oggolovin, спасибо за ответ. Очень ясно: \ d + будет означать, что он будет захватывать любое количество цифр, правильно? – Guagua

+0

@Guagua Да, '+' означает от 1 до бесконечности. Если вам нужно ровно 3, используйте '{3}' вместо '+'. – ovgolovin

+0

Я знаю, что это глупый вопрос, re.findall (r ' что это за r для? – Guagua

0

Это не самый эффективный код в мире, но это, вероятно, еще лучше, чем регулярное выражение:

tokens = teststring.split() 
numlist = [val for key, val in zip(tokens, tokens[1:]) if key == 'number:'] 

для последующей деятельности и более общих запросов:

def find_next_tokens(teststring, test): 
    tokens = teststring.split() 
    return [val for key, val in zip(tokens, tokens[1:]) if test(key)] 

, которые могли бы можно назвать:

find_next_tokens(teststring, lambda s: s.startswith('number') and s.endswith(':')) 

Это поможет, если ключи для поиска поступают от пользователя:

find_next_tokens(teststring, lambda s: s in valid_keys) 
+0

Не могли бы вы объяснить, почему решение лучше, чем регулярное выражение? эффективности или чего-то еще? – Guagua

+0

Regexes сложно отлаживать, если вам это не нужно, я бы рекомендовал не использовать его. Я нахожу это намного проще, чтобы сказать, что происходит, и это не больше кода, чем регулярное выражение +, переводящее данные соответствия. Удачи, если вы когда-нибудь захотите получить список ключей от пользователя и проанализировать это с помощью регулярного выражения. – tobyodavies

4

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

import re 
teststring = "This is a test of number, number: 525, number: 585, number2: 559" 
groups = re.findall(r"number2?: (\d{3})", teststring) 

groups затем содержит номера. Этот синтаксис использует группы регулярных выражений.

+0

Но нужны только 525 и 585. –

+0

спасибо Каникулы, не могли бы вы объяснить findall (r "number2 ?: (\ d {3})" – Guagua

+1

@Guagua 'number' является самоочевидным,' 2? 'Соответствует нулю или одному вхождению' 2', двоеточие и пробел соответствует двоеточию и пробелу, '(\ d {3})' соответствует и фиксирует три цифры. –

3

Вы можете попробовать это:

import re 
[int(x) for x in re.findall(r' \d+', teststring)] 

, который даст вам:

[525, 585, 559] 
+0

Это отвечает только на половину вопроса – tobyodavies

+0

Если он не ищет все 3 цифры, за которыми следует запятая, которая отвечает также на начальный вопрос –

1

Я предлагаю:

teststring = "This is a test of number, number: 525, number: 585, number2: 559" 
# The following does: "This is a test of number, number: 525, number: 585, number2: 559" -> ["525, number", "585, number2", "559"] 
a = teststring.split(': ')[1:] 
# The following does: ["525, number", "585, number2", "559"] -> ["525", " number", "585", " number2", "559"] 
b = [i.split(',') for i in a] 
# The following does: [["525", " number"], ["585", " number2"], ["559"]] -> ["525", "585", "559"] 
c = [i[0] for i in b] 
>>> c 
['525', '585', '559'] 
+1

, что это делает? [1:] – Guagua

+1

@Guagua Если: a = [a, b, c, d]; a [1:] = [b, c, d] –

+0

также, a [2:] = [c, d] –