【问题标题】:Making Python RegEx use variables for string expressions使 Python RegEx 将变量用于字符串表达式
【发布时间】:2011-09-30 15:55:33
【问题描述】:

我有一个 .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.'

【问题讨论】:

  • 你能发布一个准确的测试用例输入吗?
  • 您的代码有两个问题。首先有一个额外的},其次我想你的意思是row["Replacement"]而不是row[replacement]
  • 其次,CPP,为了帮助您,我们真的需要知道row['Pattern']row['Replacement']v 的值是什么。
  • 对不起!是的,我的意思是 row["Replacement"],错字(我之前有一个格式为 "%(replacement)s" % {"replacement": row["Replacement"]} 的字符串,但我只是为了便于阅读而将其取出)。 (现已修复)
  • @Kevin:不要在评论中发布输入,通过编辑将其添加到原始帖子中。

标签: python regex string variables syntax


【解决方案1】:

您的问题是您的模式值实际上不是您想要的正则表达式模式,您的正则表达式模式被包装在一个额外的字符串中。

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

【讨论】:

  • 确实有道理,eval 在 '\.' 方面犯了一些错误因为反斜杠被读取为文字被翻译为'\\。'谢谢安德鲁!
【解决方案2】:

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

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

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

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

【讨论】:

  • 对不起,似乎什么也没做:我认为 r 是 python 正则表达式的可选。
  • r 表示原始字符串。如果你在模式的值中有 r,它将是一个文字 r 而不是告诉 python 后面是一个原始字符串。
  • 因此对于输入输出,我已更改为:0,'(?i)\s+','' 1,'(?i)&','and' 2,'(? i)\bAssoc\b\.?','Association' 这就是您删除“r”字符的意思吗?
  • 查看我的编辑。您可以将 row['Pattern'] 放入 eval 以使用 r 前缀
猜你喜欢
  • 2019-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-17
  • 2022-01-18
  • 2019-04-24
  • 1970-01-01
相关资源
最近更新 更多