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

Python 匹配除特定少数词外的所有词以用于替换,数学表达式用例,python,regex,Python,Regex,串连 x='(var1 * 1.3e4 + abc)/log(blabla+2E3)' 我想将var1、abc和blabla替换为'1',比如说传递到ast,看看这是否是一个正确的表达式我不想碰log或e或e。当然,还有一些事情我可能想跳过,比如sin 目前我使用的是 for match in re.findall(r'[a-zA-Z]+',x): if match.startswith('log') or match.lower()=='e': continue x = x.

串连

x='(var1 * 1.3e4 + abc)/log(blabla+2E3)'
我想将
var1
abc
blabla
替换为
'1'
,比如说传递到
ast
,看看这是否是一个正确的表达式我不想碰
log
e
e
。当然,还有一些事情我可能想跳过,比如
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

code

用法 创建异常数组(如下所示)并加入
上的列表。另外,请注意,
re.escape
并非总是必需的,但我想我会展示它,以演示如何使用普通字符串和正则表达式创建此联接列表(如果您需要这样做的话)


解释
  • \b
    将位置断言为单词边界
  • (?!(?:此处填充)\b)
    消极前瞻确保以下内容不匹配
    • (?:stuff here)
      这包含异常的合并列表,例如
      log
      sin
      cos
      、或数字(
      [+-]?\d*\。?\d+(?:e[+-]?\d+)
      )等
  • \w+
    匹配一个或多个单词字符
  • \b
    将位置断言为单词边界
代码

用法 创建异常数组(如下所示)并加入
上的列表。另外,请注意,
re.escape
并非总是必需的,但我想我会展示它,以演示如何使用普通字符串和正则表达式创建此联接列表(如果您需要这样做的话)


解释
  • \b
    将位置断言为单词边界
  • (?!(?:此处填充)\b)
    消极前瞻确保以下内容不匹配
    • (?:stuff here)
      这包含异常的合并列表,例如
      log
      sin
      cos
      、或数字(
      [+-]?\d*\。?\d+(?:e[+-]?\d+)
      )等
  • \w+
    匹配一个或多个单词字符
  • \b
    将位置断言为单词边界

帮你自己一个忙,找一个合适的表达式解析器:@Pavel如果我理解正确,它指的是“数字字符串”,比如,字符串中没有“abc”。这不是可选的,在我的实际用例中,替换不仅仅是“1”,而是真正的用户变量。在我确定表达式有效且所有变量都可以从给定的集合中识别之前,我不会替换中的任何内容。请帮自己一个忙,找一个合适的表达式解析器:@Pavel如果我理解正确,它指的是“数值字符串”,例如,字符串中没有“abc”。这不是可选的,在我的实际用例中,替换不仅仅是“1”,而是真正的用户变量。在我确定表达式是有效的,并且所有变量都可以从给定的集合中识别出来之前,我不会替换中的任何内容。非常令人印象深刻,而且解释得很透彻。易于扩展。注意,
e
可能是大写,后面可能跟有符号。最好在例外列表中使用
e[^\w]
。另外,这里不需要
+
。@kabanus是否也不区分大小写?基本上,所有的东西都不区分大小写吗?如果你这样做的话,还不如把它们做成。这将是最灵活的-可能只是一个
re.IGNORECASE
。我已经说过我认为答案很好,你让它变得更好了。我唯一需要补充的是,异常
r“\d+(?:e\d+)”
将在
1.2E+23
上失败,这是有效的。您只需在
\d
之前添加一个
[+-]?
,并在末尾删除不需要的
+
(一个已足够检查)。@kabanus请查看新更新。我改变了正则表达式的数字部分。非常令人印象深刻,而且解释得很透彻。易于扩展。注意,
e
可能是大写,后面可能跟有符号。最好在例外列表中使用
e[^\w]
。另外,这里不需要
+
。@kabanus是否也不区分大小写?基本上,所有的东西都不区分大小写吗?如果你这样做的话,还不如把它们做成。这将是最灵活的-可能只是一个
re.IGNORECASE
。我已经说过我认为答案很好,你让它变得更好了。我唯一需要补充的是,异常
r“\d+(?:e\d+)”
将在
1.2E+23
上失败,这是有效的。您只需在
\d
之前添加一个
[+-]?
,并在末尾删除不需要的
+
(一个已足够检查)。@kabanus请查看新更新。我更改了正则表达式的数字部分。
\b(?!(?:[+-]?\d*\.?\d+(?:e[+-]?\d+)?|log|sin|cos)\b)\w+\b
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)