使Python RegEx使用变量用于字符串表达式

时间:2011-07-07 17:13:26

标签: python regex string variables syntax

我有一个.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 个答案:

答案 0 :(得分:2)

如果删除模式周围的r',它将起作用。

所以匹配的模式。应该像'\'一样简单。而不是“r'\。'”

问题是你的模式中的r被视为文字r而不是原始字符串含义。

所以你也可以尝试:     v = re.sub(eval(row ['Pattern']),row ['Replacement'],v)

答案 1 :(得分:2)

您的问题是您的模式值实际上不是您想要的正则表达式模式,您的正则表达式模式包含在附加字符串中。

例如,在您的词典中,您具有值"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