python正则表达式匹配组替换

2024-06-16 11:28:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试用AndroidManifest.xml批量生成一组要发布的通道apk包。在

<meta-data android:value="CHANNEL_NAME_TO_BE_DETERMINED" android:name="UMENG_CHANNEL"/> 从xml文件。在

通道配置保存在配置文件中,如下所示:

channel_name    output_postfix  valid 
"androidmarket" "androidmarket" true

以下是我尝试的:

^{pr2}$

它将整个<meta-data android:value="CHANNEL_NAME_TO_BE_DETERMINED" android:name="UMENG_CHANNEL"/>替换为androidmarket,这显然不是我需要的。然后我发现问题是pattern.match(each_config_line)返回一个匹配结果,结果组中的一个是“CHANNEL_NAME_TO_BE_DETERMINED”。我也尝试过给一些替换实现函数,但还是失败了。在

那么,既然我已经成功地找到了模式,那么如何正确地替换匹配的结果组元素呢?在


Tags: tonamedatavaluechannelxmlbe批量
3条回答

我建议一种不同的方法:将xml保存为模板,用标准Python字符串操作替换占位符。在

例如

AndroidManifest_template.xml:

<meta-data android:value="%(channel_name)s" android:name="UMENG_CHANNEL"/>

python:

manifest_original_xml_fh = open("../AndroidManifest_template.xml", "r")
manifest_xml_fh = open("../AndroidManifest.xml", "w")
for each_config_line in manifest_original_xml_fh:
    each_config_line = each_config_line % {'channel_name': channel_name}
    print each_config_line

要仅捕获元数据标记的值,您需要更改正则表达式:

<meta-data\sandroid:value=\"([^"]*)\"\sandroid:name=\"UMENG_CHANNEL\".*

我特别修改了这一部分:

\"(.*)\"-这是一个贪婪的匹配,因此只要表达式的其余部分匹配,它就会继续并匹配尽可能多的字符

\"([^"]*)\"-它将匹配任何不是双引号的内容。匹配结果仍将在第一个捕获组中

如果您想执行替换操作,一个更好的主意可能是捕获您希望保持不变的内容—我不是python专家,但类似这样的方法可能会奏效:

^{pr2}$

\1是backreference 1,也就是说,它获得第一个捕获组匹配的内容

我想你的误解是,所有匹配的都会被替换。如果你想保留模式中的内容,你必须捕获它并重新插入到替换字符串中。在

或使用lookaround断言只匹配要替换的内容

试试这个

pattern = re.compile('(?<=<meta-data\sandroid:value=\")[^"]+')
for each_config_line in manifest_original_xml_fh:
    each_config_line = re.sub(pattern, channel_name, each_config_line)

(?<=<meta-data\sandroid:value=\")是一个肯定的lookbehind断言,它确保此文本在前面,但与之不匹配(因此不会被替换)

[^"]+将匹配任何非"

看到了here on Regexr

相关问题 更多 >