Python:替换与特定正则表达式不匹配的字符串部分



我需要对字符串中与正则表达式不匹配的部分进行url编码。目前的解决方案(如下(是:

  1. 选择我匹配的正则表达式(###.*##(
  2. 将找到的子字符串放在列表中,并用一些不可编码的索引替换它们~~1~~
  3. 对所有内容进行编码(整个url(
  4. 把我找到的元素放回去

我有这个代码可以工作。但我相信它可以做得更好,只需一次解析就可以查找与正则表达式不匹配的字符串部分。每次这样做都会增加巨大的开销。

import re
from itertools import count
import urllib.parse
def replace_parts(url):
parts = []
counter = count(0)
def replace_to(match):
match = match.group(0)
parts.append(match)
return '~~' + str(next(counter)) + '~~'

def replace_from(match):
return parts[next(counter)]

url = re.sub(r'##(.*?)##', replace_to, url)
url = urllib.parse.quote(url)
counter = count(0)
url = re.sub(r'~~([0-9]+)~~', replace_from, url)
print (url)
url1 = "http://google.com?this_is_my_encodedurl##somethin##&email=##other##tr"
url = replace_parts(url1)
# this becomes http%3A%2F%2Fgoogle.com%3Fthis_is_my_encodedurl##somethin##%0A%26email%3D##other##tr

您可以使用re.sub来匹配##.*?##模式,也可以使用它前面的文本,这样您就可以将两类文本作为一对。然后只在回调函数的第一部分应用URL编码。为了处理输入的结束,允许第二部分是##.*?##模式或输入的结束($(:

def replace_parts(url):
return re.sub(r'(.*?)(##.*?##|$)', 
lambda m: urllib.parse.quote(m[1]) + m[2], 
url)

另一个使用re.sub和lambda的选项,使用捕获组和带有交替的匹配。

在lambda中,检查捕获组1是否存在。如果是,则应用urllib.parse.quot,然后返回。如果没有组1,则返回匹配项。

有关匹配项和组,请参阅regex演示。

图案与匹配

  • ##S*?##在##
  • |
  • ((?:(?!##.*?##)S)+)在组1中捕获不直接跟在##...##后面的字符序列

示例

import re
import urllib.parse
pattern = r"##S*?##|((?:(?!##.*?##)S)+)"
def replace_parts(url):
return re.sub(
pattern,
lambda m: urllib.parse.quote(m[1]) if m[1] else m[0],
url
)

s = "http://google.com?this_is_my_encodedurl##somethin##&email=##other##tr"
print(replace_parts(s))

输出

http%3A//google.com%3Fthis_is_my_encodedurl##somethin##%26email%3D##other##tr

最新更新