反转正则表达式替换
给定一个用正则表达式表示的字符串转换,有没有简单的方法可以在Python中反向这个转换呢?
举个例子,假设有这样的转换:
def f(x): return re.sub('foo((:?bar)?)', r'\1', x)
它把 'foobar'
转换成 'bar'
,把 'foo'
转换成空字符串。我想得到:
def g(x): return re.sub('((:?bar)?)', r'foo\1', x)
这个转换是反向的,也就是说:
f(g(x)) == x
显然,并不是所有的正则表达式替换都是一一对应的,但我希望能找到一种方法,得到一个可能的输入值 g(x)
,这样就能从原来的替换中得到给定的输出 x
。
我为什么想这么做呢?因为我想根据解析 Apache 配置文件中的 AliasMatch
指令,生成任意文件系统路径的URL。
2 个回答
0
在这个例子中,实际上发生的事情是:
xy? -> $1
y? -> x$1
我不太确定你想要什么——多给一些例子会更好——但我觉得这个通用公式可以扩展一下,至少可以涵盖更多简单的情况。
2
你的例子不太对;('(bar)?', 'foo$1')
其实并不是 ('foo(bar)?', '$1')
的反向操作。
如果你尝试一下(暂时不考虑分组替换):
import re
re.sub(r'(bar)?', 'foo', 'xyz')
你会得到 fooxfooyfoozfoo
。
这是因为 (bar)?
可以匹配空字符串,而空字符串在字符串的每个可能位置都存在。
我建议在遇到这种简单例子的问题时,可能需要换个思路来解决你真正想做的事情。
(我上面提到的分组是因为在Python中其实不太适用。如果你用 re.sub(r'(bar)?', r'foo\1', 'xyz')
,如果 (bar)?
被跳过,就会出错。你可以用 ((bar)?)
来解决这个问题,这样外层的分组就不会被省略。不过这和你的问题关系不大。)