python - 使用否定集 [^] 和什么?否定同一行中的子字符串
问题描述
我正在编写一个解析器,而不是将LaTeX
数学转换为与 pythoneval()
兼容的字符串。
我到了一个点,我有一个看起来像这样的字符串:
\sqrt{4m/s} - \frac{3v+10.5v}{20a-8a} +1/2
注意仍然主要是LaTeX
语法,以及一些任意的“单位”字母。然后我使用下面的否定集来替换除否定集中的所有内容。
mathstr = re.sub('[^0-9*()/+\-.Q]','',mathstr)
如何包含子字符串“sqrt”,以便它可以以类似的方式工作,最好是在相同的正则表达式中?
现在我的工作是用' \sqrt
'替换' Q
',执行上面的代码行,然后将' Q
'设置为' sqrt
'之后,我从上述语法到eval()
语法的完整例程如下:
mathstr = mathstr.replace(" ","")
if pwrRe.search(mathstr):
mathstr = re.sub(pwrRe,'**',mathstr)
if MultiplyRe.search(mathstr):
mathstr = re.sub(MultiplyRe,'*',mathstr)
if DivideRe.search(mathstr) or sqrtRe.search(mathstr):
mathstr = re.sub('\\\\frac{','(',mathstr)
mathstr = re.sub('\\\\sqrt{','\\\\sqrt(',mathstr)
mathstr = re.sub('}{',')/(',mathstr)
mathstr = re.sub('}',')',mathstr)
mathstr = re.sub('[/*+\-^][a-zA-Z]','',mathstr)
mathstr = re.sub('\\\\sqrt','Q',mathstr)
mathstr = re.sub('[^0-9*()/+\-.Q]','',mathstr)
mathstr = re.sub(r'Q','sqrt',mathstr)
这导致eval()
语法:
sqrt(4)-(3+10.5)/(20-8)+1/2
但这很草率,如果我可以在一行中将字符和子字符串“列入白名单”,从而消除所有其他出现的字符,那么它在许多领域都会很有用。
编辑:
随着我继续扩展我的脚本,这个列表会变得更长,但现在我想匹配以下内容并丢弃其他所有内容:
0123456789()/*+-^sqrt <-- only sqrt when it's a substring
这里有一些例子:
Before: sqrt(5s+2s)+(3s**2/9s)
After: sqrt(5+2)+(3**2/9)
Before: sqrt(4*(5+2)/(2))\$
After: sqrt(4*(5+2)/(2))
Before: sqrt(4v/a)-(3v+10.5v)/(20a-8a)+1/2ohms
After: sqrt(4)-(3+10.5)/(20-8)+1/2
除了仅匹配这些字符之外,还有一些细微差别。在我的第一个示例中,您可以看到我有 v/a,即使那里有一个“/”,我也将其删除。
解决方案
与其“删除”未指定的字符,不如“保留”指定的字符——这很容易,因为您已经否定了该组:
[0-9*()/+\-.Q]
然后你可以添加任何你想要的替代文字,例如:
[0-9*()/+\-.Q]|sqrt
在 Python 中,这可能看起来像,使用join
and re.findall()
:
tests = [
('sqrt(5s+2s)+(3s**2/9s)', 'sqrt(5+2)+(3**2/9)'),
('sqrt(4*(5+2)/(2))\$', 'sqrt(4*(5+2)/(2))'),
('sqrt(4v/a)-(3v+10.5v)/(20a-8a)+1/2ohms)', 'sqrt(4)-(3+10.5)/(20-8)+1/2')
]
import re
for (before, expected) in tests:
matches = re.findall(r"[0-9*()/+\-.Q]|sqrt", before)
after = ''.join(matches)
is_ok = (after == expected)
print(after, is_ok, '' if is_ok else expected)
输出:
sqrt(5+2)+(3**2/9) 真 sqrt(4*(5+2)/(2)) 真 sqrt(4/)-(3+10.5)/(20-8)+1/2) 错误 sqrt(4)-(3+10.5)/(20-8)+1/2
(由于第一个正斜杠,最后一个与您的期望不匹配,但这确实超出了问题的范围。)
推荐阅读
- java - 必填字段的 Json 请求验证 - springboot rest-api
- azure - 没有 IP 地址的虚拟网络中容器组之间的网络连接
- angular - 嵌套的 ngx-bootstrap 模态:回调函数订阅 onHidden 的问题
- text - 在 SwiftUI 中减少文本的行距
- python - 从字典的每个键中随机采样一个元素
- c# - 如何转换 GetEnumerator()?
- google-cloud-platform - 在云控制台中运行 kubernetes 命令返回超时
- javascript - 在 Mongoose (JavaScript) 中检查是否有任何符合特定条件的文档
- vue.js - 在 vuejs 的伊斯坦布尔、摩卡和 vue-test-utils 的覆盖范围内找不到 .vue 文件
- mysql - MYSQL 触发器 - 使用 WHERE 条件更新特定行