[英]python search/replace regex with sed-like expression
我想在Python中实现类似sed的搜索和替换。
现在显然,Python具有re
模块:
import re
re.sub("([A-Z]+)", r"\1-\1", "123 ABC 456")
但是,我想在单个字符串中指定搜索/替换操作,例如在sed中(暂时不留任何转义问题):
s/([A-Z]+)/\1-\1/g
我之所以喜欢这种语法,是因为实际的搜索和替换规范由用户提供,并且我认为对于用户而言,指定单个搜索/替换字符串而不是模式和模板都更为简单。
我只对sed的s
(搜索/替换)命令感兴趣,因为它仅用于单行(无特殊扩展名)。 用例实际上是允许用户为主机名提供字符串转换(带有组)。
有任何想法吗?
我最初的想法只是将它分割为/
并将其作为args传递给re.sub
。
事实证明这是相当复杂的,并且我敢肯定它不是防弹的,所以我以此为起点。
问题是,如果我们要处理斜杠,例如用反斜杠替换斜杠,该怎么办。 然后sed表达式将是
's/\\/\//g'
我必须用没有反斜杠的斜杠来分割它
_, pattern, repl, options = re.split(r'(?<!\\)/', sed)
为了使其更加复杂,可以在shash之前加上两个反斜杠,因此:
_, pattern, repl, options = re.split(r'(?<![^\\]\\)/', sed)
re.sub
看起来像
re.sub(pattern, repl, s, count='g' not in options)
Ups,不,在Python中,不必转义斜杠,因此:
re.sub(pattern, re.sub(r'\\/', '/', repl), s, count='g' not in options)
>>> import re
>>> s = r'\some\windows\path'
>>> sed = r's/\\/\//g'
>>> _, pattern, repl, options = re.split(r'(?<![^\\]\\)/', sed)
>>> re.sub(pattern, re.sub(r'\\/', '/', repl), s, count='g' not in options)
'/some/windows/path'
Python的re
不支持此语法。 如果要使用这样的工具,则需要开发自己的API,因此必须解析类似sed的命令并执行相应的re
函数。
您可以编写一个函数,给定类似于sed的s/
命令,对其进行解析,然后返回相应的re
函数。 然后可以在任何字符串上使用此返回的函数。
def run_sed_sub(command):
regex = re.compile(r"(?!=\\)/") # split on unescaped slashes
parts = regex.split(command)
if parts[0] != 's':
raise ValueError("Not a sub command")
regex = re.compile(parts[1])
return lambda s: regex.sub(parts[2], s)
>>> func = run_sed_sub(r"s/Hello/Goodbye/g")
>>> print(func("Hello, world!"))
Goodbye, world!
>>> func = run_sed_sub(r"s/([A-Z]+)/\1-\1/g")
>>> print(func("123 ABC 456"))
123 ABC-ABC 456
有些前卫的情况可能会很痛苦,例如换行,但想法就在这里。 您可能还想用普通斜杠替换以sed方式转义的斜杠,因此, parts = [re.sub(r"\\\\/", "/", p) for p in parts]
应该可以解决问题。
我也不知道最后如何处理这些标志,但是我想如果知道期望的行为并不难。
尽管如此,我还要补充一点,实现这种工具的样板可能比仅仅学习Python的re
还要重要。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.