Заставить Python RegEx использовать переменные для строковых выражений - PullRequest
4 голосов
/ 07 июля 2011

У меня есть файл .csv с шаблонами регулярных выражений, которые я хочу сопоставить, а также шаблонами замены, которые я хочу.Некоторые из них чрезвычайно просты, например, "."-> "" или "," -> "".

Однако, когда я запускаю следующий код, он не распознает переменные, и шаблон никогда не сопоставляется.

                f = open('normalize_patterns.csv', 'rU')
                c = csv.DictReader(f)
                for row in c:
                    v = re.sub(row['Pattern'],row['Replacement'],v)

Впоследствии v никогда не изменяется, и я не могу понять, почему.Когда я запускаю простой случай

                v = re.sub("\.", "", v)
                v = re.sub(",", "", v)

, все точки и запятые удаляются.Любая помощь по этому вопросу была бы удивительной.Заранее спасибо!(Я почти уверен, что файл .csv отформатирован правильно, я запустил его только с регистром "." И "", и он по-прежнему не работает по определенной причине)выходы печатного ряда.(Спасибо, Дэвид!)

{'Pattern': "r'(?i)&'", 'ID': '1', 'Replacement': "'and'"}
{'Pattern': "r'(?i)\\bAssoc\\b\\.?'", 'ID': '2', 'Replacement': "'Association'"}
{'Pattern': "r'(?i)\\bInc\\b\\.?'", 'ID': '3', 'Replacement': "'Inc.'"}
{'Pattern': "r'(?i)\\b(L\\.?){2}P\\.?'", 'ID': '4', 'Replacement': "''"}
{'Pattern': "r'(?i)\\bUniv\\b\\.?'", 'ID': '5', 'Replacement': "'University'"}
{'Pattern': "r'(?i)\\bCorp\\b\\.?'", 'ID': '6', 'Replacement': "'Corporation'"}
{'Pattern': "r'(?i)\\bAssn\\b\\.?'", 'ID': '7', 'Replacement': "'Association'"}
{'Pattern': "r'(?i)\\bUnivesity\\b'", 'ID': '8', 'Replacement': "'University'"}
{'Pattern': "r'(?i)\\bIntl\\b\\.?'", 'ID': '9', 'Replacement': "'International'"}
{'Pattern': "r'(?i)\\bInst\\b\\.?'", 'ID': '10', 'Replacement': "'Institute'"}
{'Pattern': "r'(?i)L\\.L\\.C\\.'", 'ID': '11', 'Replacement': "'LLC'"} 
{'Pattern': "r'(?i)Chtd'", 'ID': '12', 'Replacement': "'Chartered'"}
{'Pattern': "r'(?i)Mfg\\b\\.?'", 'ID': '13', 'Replacement': "'Manufacturing'"}
{'Pattern': 'r"Nat\'l"', 'ID': '14', 'Replacement': "'National'"}
{'Pattern': "r'(?i)Flordia'", 'ID': '15', 'Replacement': "'Florida'"}
{'Pattern': "r'(?i)\\bLtd\\b\\.?'", 'ID': '16', 'Replacement': "'Ltd.'"}
{'Pattern': "r'(?i)\\bCo\\b\\.?'", 'ID': '17', 'Replacement': "'Company'"}
{'Pattern': "r'(?i)\\bDept\\b\\.?i\\'", 'ID': '18', 'Replacement': "'Department'"}
{'Pattern': "r'(?i)Califronia'", 'ID': '19', 'Replacement': "'California'"}
{'Pattern': "r'(?i)\\bJohn\\bHopkins\\b'", 'ID': '20', 'Replacement': "'Johns Hopkins'"}
{'Pattern': "r'(?i)\\bOrg\\b\\.?'", 'ID': '21', 'Replacement': "'Organization'"}
{'Pattern': "r'(?i)^[T]he\\s'", 'ID': '22', 'Replacement': "''"}
{'Pattern': "r'(?i)\\bAuth\\b\\.?'", 'ID': '23', 'Replacement': "'Authority'"}
{'Pattern': "r'.'", 'ID': '24', 'Replacement': "''"}
{'Pattern': "r','", 'ID': '25', 'Replacement': "''"}
{'Pattern': "r'(?i)\\s+'", 'ID': '0', 'Replacement': "''"}

А вот несколько строк файла CSV (Открыт в TextMate)

0,r'(?i)\s+',''
1,r'(?i)&','and'
2,r'(?i)\bAssoc\b\.?','Association'
3,r'(?i)\bInc\b\.?','Inc.'

Ответы [ 2 ]

2 голосов
/ 07 июля 2011

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

Например, в вашем словаре у вас есть значение "r'.'", котороеВы используете в качестве шаблона.Ваш код будет работать re.sub("r'.'", "", v), что, вероятно, не то, что вы хотите:

>>> re.sub("r'.'", "", "This . won't match")
"This . won't match"
>>> re.sub("r'.'", "", "This r'x' will match")
'This  will match'

Чтобы исправить это, вы должны вернуться туда, где вы добавляете регулярное выражение в словарь, и прекратить делать все, что вызываетперенос строкиЭто может быть что-то вроде row['Pattern'] = repr(regex).

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

2 голосов
/ 07 июля 2011

Если вы удалите r '' вокруг шаблона, он будет работать.

Итак, шаблон, который соответствует. должно быть так же просто, как '\.' вместо "r '\.'"

Проблема в том, что в вашем шаблоне r воспринимается как литерал r вместо необработанного значения строки.

Так что вы также можете попробовать: v = re.sub (eval (строка ['Pattern']), строка ['Replacement'], v)

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