我想替换连续符号,例如;
这是一只狗???
到
这是一只狗?
我正在使用
str = re.sub("([^\s\w])(\s*\1)+", "\\1",str)
但是我注意到这可能会替换我的文本中可能发生的网址中的符号。
喜欢http://example.com/this--is-a-page.html
有人可以给我一些如何改变我的正则表达式的建议吗?
答案 0 :(得分:2)
因此,您希望释放HTML等不规则语言的正则表达式的强大功能。首先,搜索SO以“使用正则表达式解析HTML”以找出可能不是一个好主意的原因。
然后考虑以下事项:您想要替换(可能是用户输入的)文本中的重复符号。您不希望在URL中替换它们。你怎么知道URL是什么?它们并不总是以http
开头 - 假设ars.userfriendly.org
可能是一个后跟包含重复符号的较长路径的网址。
此外,你会发现许多你绝对不想替换的重复符号(想想嵌套的括号(比如这个)),其中一些可能在页面上的<script>
内你是我想到了工作(||
,&&
等。
所以你可能想出像
这样的东西(?<!\b(?:ftp|http|mailto)\S+)([^\\|&/=()"'\w\s])(?:\s*\1)+
恰好在此页面的源代码上工作,但在其他情况下肯定会失败(例如,如果网址不是以ftp
,http
或mailto
开头的话。另外,它在Python中不起作用,因为它在lookbehind中使用变量重复。
总而言之,您可能无法使用真正的解析器解析HTML,查找正文,应用正则表达式并将其写回。
修改强>
好的,您已经在处理已解析的文本,但它仍然可能包含URL。
然后尝试以下方法:
result = re.sub(
r"""(?ix) # case-insensitive, verbose regex
# Either match a URL
# (protocol optional (if so, URL needs to start with www or ftp))
(?P<URL>\b(?:(?:https?|ftp|file)://|www\.|ftp\.)[-A-Z0-9+&@#/%=~_|$?!:,.]*[A-Z0-9+&@#/%=~_|$])
# or
|
# match repeated non-word characters
(?P<rpt>[^\s\w])(?:\s{0,100}(?P=rpt))+""",
# and replace with both captured groups (one will always be empty)
r"\g<URL>\g<rpt>", subject)
重新编辑:嗯,Python在(?:\s*(?P=rpt))+
部分窒息,说+
没有什么可重复的。看起来像Python中的错误(可以使用(.)(\s*\1)+
重现,而(.)(\s?\1)+
可以使用)...
重新编辑:如果我将*
替换为{0,100}
,则正则表达式会编译。但现在Python抱怨一个无与伦比的群体。显然,如果没有参加比赛,你就不能在替换中引用一个组。我放弃...... :(