我正在尝试替换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
以下是我的尝试:
manifest_original_xml_fh = open("../AndroidManifest_original.xml", "r")
manifest_xml_fh = open("../AndroidManifest.xml", "w")
pattern = re.compile('<meta-data\sandroid:value=\"(.*)\"\sandroid:name=\"UMENG_CHANNEL\".*')
for each_config_line in manifest_original_xml_fh:
each_config_line = re.sub(pattern, channel_name, each_config_line)
print each_config_line
它将整个<meta-data android:value="CHANNEL_NAME_TO_BE_DETERMINED" android:name="UMENG_CHANNEL"/>
替换为androidmarket
,这显然不是我的需要。然后我发现问题是pattern.match(each_config_line)
返回匹配结果,其中一个结果组是“CHANNEL_NAME_TO_BE_DETERMINED”。我也试过给一些替换实现函数,但仍然失败了。
所以,既然我已成功找到模式,我该如何正确替换匹配的结果组元素?
答案 0 :(得分:1)
我建议采用不同的方法:将xml保存为模板,使用标准Python字符串操作替换占位符。
E.g。
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
答案 1 :(得分:0)
要仅捕获元数据标记的值,您需要更改正则表达式:
<meta-data\sandroid:value=\"([^"]*)\"\sandroid:name=\"UMENG_CHANNEL\".*
具体来说,我改变了这一部分:
\"(.*)\"
- 这是一个贪婪的匹配,所以只要表达式的其余部分匹配,它就会继续并匹配尽可能多的字符
到
\"([^"]*)\"
- 它将匹配任何不是双引号的东西。匹配结果仍将在第一个捕获组
如果你想做替换的事情,一个更好的想法可能是捕获你想要保持不变的东西 - 我不是python专家,但是这样的东西可能会起作用:
re.sub(r'(<meta-data\sandroid:value=\")[^"]*(\"\sandroid:name=\"UMENG_CHANNEL\".*)'
, r'\1YourNewValue\2', s)
\1
是反向引用1 - 即它获得第一个捕获组匹配的内容
答案 2 :(得分:0)
我认为你的误解是,所有匹配的东西都将被取代。如果你想保留模式中的东西,你必须捕获它并将其重新插入替换字符串中。
或仅使用外观断言匹配您要替换的内容
试试这个
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断言,它确保此文本在之前,但不匹配(因此不会被替换)
[^"]+
将匹配任何非"