匹配除特定少数之外的所有单词用于替换目的,数学表达式用例

时间:2017-12-19 17:43:44

标签: python regex

在字符串

x='(var1 * 1.3e4 + abc)/log(blabla+2E3)'

我想将var1abcblabla替换为'1',比如传递到ast并查看这是否是正确的表达式。 我不想触及 logeE。当然,还有其他一些我可能想要跳过的内容,例如sin

目前我正在使用类似

的内容
for match in re.findall(r'[a-zA-Z]+',x):
    if match.startswith('log') or match.lower()=='e': continue
    x = x.replace(string,'1')

日志可以有几种风格,因此startswith - 显然不会对任何情况起作用。 我希望一次性使用 re.sub

1 个答案:

答案 0 :(得分:2)

代码

See regex in use here

\b(?!(?:[+-]?\d*\.?\d+(?:e[+-]?\d+)?|log|sin|cos)\b)\w+\b

用法

创建一系列例外(如下所示)并加入|上的列表。此外,请注意re.escape并不总是必要的,但我想我会展示它如何使用普通字符串和正则表达式创建此连接列表(如果是这样的话)你需要做什么)。

See code in use here

import re

exceptions = [
    re.escape("log"),
    re.escape("sin"),
    re.escape("cos"),
    r"[+-]?\d*\.?\d+(?:e[+-]?\d+)?"
]

s = "(var1 * 1.3e4 + abc)/log(blabla+2E3)*1.2E+23"
r = r"\b(?!(?:" + "|".join(exceptions) + r")\b)\w+\b"

print re.sub(r, "1", s, 0, re.I)

说明

  • \b断言位置为单词边界
  • (?!(?:stuff here)\b)否定前瞻确保后续内容不匹配
    • (?:stuff here)这包含加入的例外列表,例如logsincos或数字([+-]?\d*\.?\d+(?:e[+-]?\d+)?)等。
  • \w+匹配一个或多个单词字符
  • \b断言位置为单词边界