2013-12-09 3 views
0

Я пытаюсь выполнить итерацию по списку строк, сохраняя только те, которые соответствуют шаблону именования, который я указал. Я хочу принять любую запись списка, которая точно соответствует шаблону, отличную от целого числа в поле переменной <SCENARIO>.Python test, если строка соответствует значению шаблона

Проверка должна быть общей. В частности, структура строки может измениться так, что нет гарантии, что <SCENARIO> всегда отображается в символе X (например, для использования списков).

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

template = 'name_is_here_<SCENARIO>_20131204.txt' 

testList = ['name_is_here_100_20131204.txt',  # should accept 
      'name_is_here_100_20131204.txt.NEW', # should reject 
      'other_name.txt']      # should reject 

acceptList = [] 

for name in testList: 
    print name 
    acceptFlag = True 
    splitTemplate = template.split('_') 
    splitName = name.split('_') 
    # if lengths do not match, name cannot possibly match template 
    if len(splitTemplate) == len(splitName): 
     print zip(splitTemplate, splitName) 
     # compare records in the split 
     for t, n in zip(splitTemplate, splitName): 
      if t!=n and not t=='<SCENARIO>': 
       #reject if any of the "other" fields are not identical 
       #(would also check that '<SCENARIO>' field is numeric - not shown here) 
       print 'reject: ' + name 
       acceptFlag = False 
    else: 
     acceptFlag = False 

    # keep name if it passed checks 
    if acceptFlag == True: 
     acceptList.append(name) 

print acceptList 
# correctly prints --> ['name_is_here_100_20131204.txt'] 
+0

Да, здесь можно использовать регулярное выражение. До сих пор у вас есть регулярное выражение? –

+0

@SimeonVisser - извините, но regex еще нет. Я знаю, что существует регулярное выражение, но я не знаком с деталями реализации. Я хотел убедиться, что это был подходящий подход, прежде чем зайти слишком далеко. Спасибо, что подтвердили. – Roberto

ответ

3

Попробуйте с re модулем для регулярных выражений в Python:

import re 

template = re.compile(r'^name_is_here_(\d+)_20131204.txt$') 

testList = ['name_is_here_100_20131204.txt', #accepted 
      'name_is_here_100_20131204.txt.NEW', #rejected! 
      'name_is_here_aabs2352_20131204.txt', #rejected! 
      'other_name.txt'] #rejected! 

acceptList = [item for item in testList if template.match(item)] 
+0

Это похоже на то, что я хотел. Я предполагаю, что единственная проблема заключается в том, что я хотел бы, чтобы 'template' был переменным, без необходимости конкретно вводить детали регулярных выражений. Другими словами, я хотел бы ввести шаблон в указанном формате и перевести код в оператор regex автоматически. Я уверен, что есть способ разбора моего шаблона в указанном вами формате - я рассмотрю следующее. Спасибо за направление. – Roberto

+0

Я использовал конкатентацию для построения обобщенной строки компиляции: 'feedNameRegex = '^' + feedName.replace ('', r '(\ d +)') + '$''. Вы видите какие-либо проблемы с этим подходом? – Roberto

+0

@Roberto Ну, мне кажется хорошо, но вы должны проверить его в своем контексте, извините за задержку! –

1

Это следует делать, я понимаю, что name_is_here просто заполнитель для алфавитно-цифровых символов?

import re 
testList = ['name_is_here_100_20131204.txt',  # should accept 
      'name_is_here_100_20131204.txt.NEW', # should reject 
      'other_name.txt', 
      'name_is_44ere_100_20131204.txt', 
      'name_is_here_100_2013120499.txt', 
      'name_is_here_100_something_2013120499.txt', 
      'name_is_here_100_something_20131204.txt'] 


def find(scenario): 
    begin = '[a-z_]+100_' # any combinations of chars and underscores followd by 100 
    end = '_[0-9]{8}.txt$' #exactly eight digits followed by .txt at the end 
    pattern = re.compile("".join([begin,scenario,end])) 
    result = [] 
    for word in testList: 
     if pattern.match(word): 
      result.append(word) 

    return result 

find('something') # returns ['name_is_here_100_something_20131204.txt'] 

EDIT: сценарий в отдельной переменной, регулярное выражение теперь только соответствует символам следуют 100, затем scenarion, затем восемь цифр с последующим .txt.

+0

Это может быть слишком общим. Я не думаю, что это гарантирует идентичное наименование везде вне требуемой переменной части. Например, пройдет 'name_is_44ere_100_20131204.txt'. – Roberto

+0

Итак, name_is_here должны быть только буквы, разделенные символом подчеркивания. Какую часть вы хотели бы держать в переменной? ? Name_is_here_100 будет постоянной строкой? Количество цифр после сценария будет исправлено? Вы можете создать регулярное выражение из переменной, если вам нужно. –

+0

Отредактировано мое решение, надеюсь, что это сработает! –

Смежные вопросы