2016-03-17 2 views
-1

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

def bork(text): 
    """ 
    Implementation of language transformation based on Swedish-Chef talk. 
    """ 

    rules = {"\be": "i", 
     "the": "zee", 
     "\Be\b": "e-a", 
     "an": "un" 
     } 

    rules = dict((re.escape(k), v) for k, v in rules.items()) 
    pattern = re.compile("|".join(rules.keys())) 
    borked = pattern.sub(lambda i: rules[re.escape(i.group(0))], text.strip()) 
    return borked 

text = """experienced""" 
print bork(text) 
# gives "experienced" 

Где оно должно указывать "ixperienced". Из-за правила \be: i. Другие преобразования хорошо работают при тестировании с большим объемом ввода, но это не помогает, пожалуйста, помогите мне.

Редактировать: Я добавил правило "\Bi\B": "ee". Который должен сделать результат "ixpereeenced". Что тоже не сработало. Я все еще получаю "experienced".

Edit2: кажется, что проблема существует в рамках правил, которые я использовал обратную косую черту, однако, я попытался использовать сырые строки и re.escape(). После этого я попытался удалить re.escape(), но это дает мне ключ ошибки в словаре вызова. (Я также хочу, чтобы выяснить, почему это происходит)

ответ

3

"\b" является забой характер, значение ASCII 8. r"\b" это буквальные символы \ и b. Используйте необработанные строки для предотвращения интерпретации управляющих последовательностей.

rules = { 
    r"\be": "i", 
    r"the": "zee", 
    r"\Be\b": "e-a", 
    r"an": "un" 
} 

Тогда, чтобы избавиться от первого re.escape() вызова.

+0

Я попробовал, не помогло. – Rockybilly

+0

Избавление от вызова re.escape() заставляет меня получить ключевую ошибку в этой ситуации. Может быть, если бы вы могли мне помочь, это могло бы решить мою проблему :( – Rockybilly

+1

@Rockybilly Проблема в том, что согласованный текст не будет равен регулярному выражению, когда регулярное выражение содержит специальные конструкторы регулярных выражений, такие как '\ b'. По этой причине вы не можете index в словарь правил с совпадающим текстом – pasztorpisti

3

Один проход re.sub, используя группы захвата, чтобы мы могли определить , который имеет вид, соответствующий этому региону. Вы могли бы упростить логику функции subst, сохраняя список моделей, вместо того, чтобы перечислить rules словарю каждый раз ...

rules = { 
    r'(\be)' : 'i', 
    r'(the)' : 'zee', 
    r'(an)' : 'un', 
    r'(\Be\b)' : 'e-a' 
} 
pattern = '|'.join(rules.iterkeys()) 

def subst(matchobj): 
    dind = [ind for (ind, val) in enumerate(matchobj.groups()) if val is not None][0] 
    return rules[[val for (ind, val) in enumerate(rules) if ind == dind][0]] 

text = 'experienced' 
re.sub(pattern, subst, text) 
1

Порядок следования регулярных выражений вопросов групп. При использовании '|', первое совпадение принимается, даже если в списке имеется более длинное совпадение. Поэтому вы не должны полагаться на dict.keys(), потому что заказ не определен. Используйте список (я думаю, вы могли бы использовать заказ Dict). Кроме того, matchobject.lastindex возвращает индекс последней (или только) сопоставленной группы.

rules = [ 
    (r'\be' , 'i' ), 
    (r'the' , 'zee'), 
    (r'an' , 'un'), 
    (r'\Bi\B', 'ee'), 
    (r'\Be\b', 'e-a' ) 
] 

pattern = '|'.join('({})'.format(rule[0]) for rule in rules) 

def subst(matchobj): 
    #print(matchobj) 
    return rules[matchobj.lastindex-1][1] 

text = 'experienced' 
re.sub(pattern, subst, text) 

возвращается:

'ixpereeenced' 
+0

Итак, какой метод выполняет несколько изменений за один проход? Ввод более длинных совпадений в конец списка правил? Или наоборот? – Rockybilly

+0

Как правило, более длинные совпадения должны быть первыми. Например, в шаблоне «a | ab» «ab» никогда не будет соответствовать, потому что «a» будет соответствовать первому - концу поиска. Но если шаблон изменен на «ab | a», «ab» может совпадать.Это может быть труднее выяснить, когда в шаблоне есть дополнительные или повторяющиеся части (например, используя *, +,? И т. Д.). – RootTwo

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